charm-openstack-dashboard/unit_tests/test_horizon_utils.py
Hervé Beraud 9da66b4cc5 Use unittest.mock instead of mock
The mock third party library was needed for mock support in py2
runtimes. Since we now only support py36 and later, we can use the
standard lib unittest.mock module instead.

Note that https://github.com/openstack/charms.openstack is used during tests
and he need `mock`, unfortunatelly it doesn't declare `mock` in its
requirements so it retrieve mock from other charm project (cross dependency).
So we depend on charms.openstack first and when
Ib1ed5b598a52375e29e247db9ab4786df5b6d142 will be merged then CI
will pass without errors.

Depends-On: Ib1ed5b598a52375e29e247db9ab4786df5b6d142
Change-Id: I718a003c5f07e390457bc39e69871c7ecb533e7b
2021-12-15 14:33:48 +00:00

655 lines
27 KiB
Python

# Copyright 2016 Canonical Ltd
#
# 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 unittest.mock import MagicMock, patch, call
from collections import OrderedDict
# import charmhelpers.contrib.openstack.templating as templating
# templating.OSConfigRenderer = MagicMock()
import hooks.horizon_utils as horizon_utils
from unit_tests.test_utils import (
CharmTestCase,
patch_open,
)
TO_PATCH = [
'config',
'get_os_codename_install_source',
'apt_update',
'apt_upgrade',
'apt_install',
'configure_installation_source',
'log',
'cmp_pkgrevno',
'os_release',
'os_application_version_set',
'reset_os_release',
'relation_ids',
'related_units',
'relation_get',
'HorizonOSConfigRenderer',
]
class TestHorizonUtils(CharmTestCase):
def setUp(self):
super(TestHorizonUtils, self).setUp(horizon_utils, TO_PATCH)
self.config.side_effect = self.test_config.get
def test_determine_packages(self):
horizon_utils.os_release.return_value = 'icehouse'
self.assertEqual(
sorted(horizon_utils.determine_packages()),
sorted([
'haproxy',
'python-novaclient',
'python-keystoneclient',
'openstack-dashboard-ubuntu-theme',
'python-memcache',
'openstack-dashboard',
'memcached']))
def test_determine_packages_mitaka(self):
horizon_utils.os_release.return_value = 'mitaka'
self.assertTrue('python-pymysql' in horizon_utils.determine_packages())
def test_determine_packages_queens(self):
horizon_utils.os_release.return_value = 'queens'
self.assertEqual(
sorted(horizon_utils.determine_packages()),
sorted(horizon_utils.BASE_PACKAGES +
['python-pymysql',
'python-neutron-lbaas-dashboard',
'python-designate-dashboard',
'python-heat-dashboard',
'python-neutron-fwaas-dashboard']))
def test_determine_packages_rocky(self):
horizon_utils.os_release.return_value = 'rocky'
self.assertEqual(
sorted(horizon_utils.determine_packages()),
sorted([p for p in horizon_utils.BASE_PACKAGES
if not p.startswith('python-')] +
horizon_utils.PY3_PACKAGES)
)
def test_determine_packages_victoria(self):
horizon_utils.os_release.return_value = 'victoria'
verify_pkgs = [
p for p in horizon_utils.BASE_PACKAGES
if not p.startswith('python-')
] + horizon_utils.PY3_PACKAGES
verify_pkgs.append('python3-mysqldb')
verify_pkgs.remove('python3-neutron-lbaas-dashboard')
verify_pkgs.remove('python3-neutron-fwaas-dashboard')
self.assertEqual(
sorted(horizon_utils.determine_packages()),
sorted(verify_pkgs)
)
def test_determine_purge_packages(self):
'Ensure no packages are identified for purge prior to rocky'
horizon_utils.os_release.return_value = 'queens'
horizon_utils.relation_ids.return_value = []
self.assertEqual(horizon_utils.determine_purge_packages(), [])
def test_determine_purge_packages_rocky(self):
'Ensure python packages are identified for purge at rocky'
horizon_utils.relation_ids.return_value = []
horizon_utils.os_release.return_value = 'rocky'
verify_pkgs = (
[p for p in horizon_utils.BASE_PACKAGES
if p.startswith('python-')] +
['python-django-horizon',
'python-django-openstack-auth',
'python-pymysql',
'python-neutron-lbaas-dashboard',
'python-designate-dashboard',
'python-heat-dashboard'])
self.assertEqual(
sorted(horizon_utils.determine_purge_packages()),
sorted(verify_pkgs))
def test_determine_purge_packages_victoria(self):
'Ensure python packages are identified for purge at victoria'
horizon_utils.relation_ids.return_value = []
horizon_utils.os_release.return_value = 'victoria'
verify_pkgs = (
[p for p in horizon_utils.BASE_PACKAGES
if p.startswith('python-')] +
['python-django-horizon',
'python-django-openstack-auth',
'python-pymysql',
'python-neutron-lbaas-dashboard',
'python-designate-dashboard',
'python-heat-dashboard',
'python3-neutron-lbaas-dashboard',
'python3-neutron-fwaas-dashboard'])
self.assertEqual(
sorted(horizon_utils.determine_purge_packages()),
sorted(verify_pkgs))
def _patch_for_dashboard_plugin_packages(self):
def relation_ids_side_effect(rname):
return {
'dashboard-plugin': [
'dashboard-plugin:0',
'dashboard-plugin:1',
],
}[rname]
horizon_utils.relation_ids.side_effect = relation_ids_side_effect
def related_units_side_effect(rid):
return {
'dashboard-plugin:0': ['r0', 'r1'],
'dashboard-plugin:1': ['r2'],
}[rid]
horizon_utils.related_units.side_effect = related_units_side_effect
def relation_get_side_effect(unit=None, rid=None):
return {
"dashboard-plugin:0/r0": {
'install-packages': '["p1", "p3", "p2"]',
'conflicting-packages': '["n2"]',
},
"dashboard-plugin:0/r1": {
'install-packages': '["p5", "p6"]',
'conflicting-packages': "",
},
"dashboard-plugin:1/r2": {
'install-packages': '["p4", "p6"]',
'conflicting-packages': '["n1"]',
},
}["{}/{}".format(rid, unit)]
horizon_utils.relation_get.side_effect = relation_get_side_effect
def test_determine_packages_dashboard_plugin(self):
'Ensure that plugins can provide their packages.'
self._patch_for_dashboard_plugin_packages()
self.assertEqual(
sorted(horizon_utils.determine_packages_dashboard_plugin()),
sorted(['p1', 'p2', 'p3', 'p4', 'p5', 'p6']))
def test_determine_packages_with_dashboard_plugin_rocky(self):
'Ensure that plugin packages are part of determine_packages()'
horizon_utils.os_release.return_value = 'rocky'
pkgs = ([p for p in horizon_utils.BASE_PACKAGES
if not p.startswith('python-')] +
horizon_utils.PY3_PACKAGES +
['p1', 'p2', 'p3', 'p4', 'p5', 'p6'])
self._patch_for_dashboard_plugin_packages()
self.assertEqual(
sorted(horizon_utils.determine_packages()),
sorted(pkgs)
)
def test_determine_purge_packages_dashboard_plugin(self):
'Ensure that plugins can provide their conflicting packages'
self._patch_for_dashboard_plugin_packages()
self.assertEqual(
sorted(horizon_utils.determine_purge_packages_dashboard_plugin()),
sorted(['n1', 'n2']))
def test_determine_purge_packages_dashboard_plugin_rocky(self):
'Ensure python packages are identified for purge at rocky'
self._patch_for_dashboard_plugin_packages()
horizon_utils.os_release.return_value = 'rocky'
verify_pkgs = (
[p for p in horizon_utils.BASE_PACKAGES
if p.startswith('python-')] +
['python-django-horizon',
'python-django-openstack-auth',
'python-pymysql',
'python-neutron-lbaas-dashboard',
'python-designate-dashboard',
'python-heat-dashboard'])
self.assertEqual(
sorted(horizon_utils.determine_purge_packages()),
sorted(verify_pkgs + ["n1", "n2"]))
@patch('charmhelpers.core.unitdata.kv')
def test_store_plugin_packages_in_kv(self, mock_kv):
'Ensure that plugin packages state can be stored.'
_key = None
_value = None
_flush = None
class MockKV():
def set(key, value):
nonlocal _key, _value
_key = key
_value = value
def flush():
nonlocal _flush
_flush = True
mock_kv.return_value = MockKV
horizon_utils.store_plugin_packages_in_kv('r1', 'u1',
['n1'],
['p1', 'p2', 'p3'])
self.assertEqual(_value,
{"conflicting_packages": ['n1'],
"install_packages": ['p1', 'p2', 'p3']})
self.assertEqual(
_key,
horizon_utils.make_dashboard_plugin_packages_kv_key('r1', 'u1'))
self.assertTrue(_flush)
@patch('charmhelpers.core.unitdata.kv')
def test_get_plugin_packages_from_kv(self, mock_kv):
'Ensure that plugin packages state can be recovered.'
# no data stored yet; ensure that it handles it gracefully
_key = None
_value = None
class MockKV():
def get(key, default=None):
nonlocal _key
_key = key
return _value
mock_kv.return_value = MockKV
self.assertEqual(horizon_utils.get_plugin_packages_from_kv('r1', 'u1'),
{"conflicting_packages": [],
"install_packages": []})
self.assertEqual(
_key,
horizon_utils.make_dashboard_plugin_packages_kv_key('r1', 'u1'))
# just packages are configured.
_key = None
_value = {"install_packages": ['p1', 'p2']}
self.assertEqual(horizon_utils.get_plugin_packages_from_kv('r1', 'u1'),
{"conflicting_packages": [],
"install_packages": ['p1', 'p2']})
# just conflicting packages are configured.
_key = None
_value = {"conflicting_packages": ['n1']}
self.assertEqual(horizon_utils.get_plugin_packages_from_kv('r1', 'u1'),
{"conflicting_packages": ['n1'],
"install_packages": []})
# configure both being stored.
_key = None
_value = {"install_packages": ['p1', 'p2'],
"conflicting_packages": ['n1']}
self.assertEqual(horizon_utils.get_plugin_packages_from_kv('r1', 'u1'),
{"conflicting_packages": ['n1'],
"install_packages": ['p1', 'p2']})
@patch.object(horizon_utils, 'get_plugin_packages_from_kv')
@patch.object(horizon_utils, 'store_plugin_packages_in_kv')
def test_update_plugin_packages_in_kv(self,
mock_store_plugin_packages_in_kv,
mock_get_plugin_packages_from_kv):
'Ensure that plugin packages state can be faithfully held'
self._patch_for_dashboard_plugin_packages()
mock_get_plugin_packages_from_kv.return_value = {
"install_packages": ["p1", "q1"],
"conflicting_packages": ["m1"],
}
(added, removed) = horizon_utils.update_plugin_packages_in_kv(
"dashboard-plugin:0", "r0")
self.assertEqual(sorted(added), ["m1", "p2", "p3"])
self.assertEqual(sorted(removed), ["n2", "q1"])
mock_store_plugin_packages_in_kv.assert_called_once_with(
"dashboard-plugin:0", "r0", ["n2"], ["p1", "p3", "p2"])
@patch('subprocess.call')
def test_enable_ssl(self, _call):
horizon_utils.enable_ssl()
_call.assert_has_calls([
call(['a2ensite', 'default-ssl']),
call(['a2enmod', 'ssl']),
call(['a2enmod', 'rewrite']),
call(['a2enmod', 'headers'])
])
def test_restart_map(self):
ex_map = OrderedDict([
('/etc/openstack-dashboard/local_settings.py',
['apache2', 'memcached']),
('/etc/apache2/conf.d/openstack-dashboard.conf',
['apache2', 'memcached']),
('/etc/apache2/conf-available/openstack-dashboard.conf',
['apache2', 'memcached']),
('/etc/apache2/sites-available/default-ssl',
['apache2', 'memcached']),
('/etc/apache2/sites-available/default-ssl.conf',
['apache2', 'memcached']),
('/etc/apache2/sites-available/default',
['apache2', 'memcached']),
('/etc/apache2/sites-available/000-default.conf',
['apache2', 'memcached']),
('/etc/apache2/ports.conf',
['apache2', 'memcached']),
('/etc/haproxy/haproxy.cfg',
['haproxy']),
('/usr/share/openstack-dashboard/openstack_dashboard/enabled/'
'_40_router.py',
['apache2', 'memcached']),
('/usr/share/openstack-dashboard/openstack_dashboard/conf/'
'keystonev3_policy.json',
['apache2', 'memcached']),
('/usr/share/openstack-dashboard/openstack_dashboard/conf/'
'cinder_policy.d/consistencygroup.yaml',
['apache2', 'memcached']),
])
self.assertEqual(horizon_utils.restart_map(), ex_map)
@patch.object(horizon_utils, 'determine_packages')
def test_do_openstack_upgrade(self, determine_packages):
self.test_config.set('openstack-origin', 'cloud:precise-havana')
self.get_os_codename_install_source.return_value = 'havana'
horizon_utils.os_release.return_value = 'icehouse'
configs = MagicMock()
determine_packages.return_value = ['testpkg']
horizon_utils.do_openstack_upgrade(configs)
configs.set_release.assert_called_with(openstack_release='havana')
self.assertTrue(self.log.called)
self.apt_update.assert_called_with(fatal=True)
dpkg_opts = [
'--option', 'Dpkg::Options::=--force-confnew',
'--option', 'Dpkg::Options::=--force-confdef',
]
self.apt_upgrade.assert_called_with(options=dpkg_opts,
dist=True, fatal=True)
self.apt_install.assert_called_with(['testpkg'], fatal=True)
self.reset_os_release.assert_called()
self.configure_installation_source.assert_called_with(
'cloud:precise-havana'
)
@patch('os.path.isfile')
@patch('os.path.isdir')
def test_register_configs(self, _isdir, _isfile):
_isdir.return_value = True
_isfile.return_value = True
self.os_release.return_value = 'havana'
configs = horizon_utils.register_configs()
confs = [horizon_utils.LOCAL_SETTINGS,
horizon_utils.HAPROXY_CONF,
horizon_utils.PORTS_CONF,
horizon_utils.APACHE_24_DEFAULT,
horizon_utils.APACHE_24_CONF,
horizon_utils.APACHE_24_SSL]
calls = []
for conf in confs:
calls.append(
call(conf, horizon_utils.CONFIG_FILES[conf]['hook_contexts']))
configs.register.assert_has_calls(calls)
@patch('os.path.isdir')
def test_register_configs_pre_install(self, _isdir):
_isdir.return_value = False
self.os_release.return_value = 'havana'
configs = horizon_utils.register_configs()
confs = [horizon_utils.LOCAL_SETTINGS,
horizon_utils.HAPROXY_CONF,
horizon_utils.PORTS_CONF,
horizon_utils.APACHE_24_DEFAULT,
horizon_utils.APACHE_24_CONF,
horizon_utils.APACHE_24_SSL]
calls = []
for conf in confs:
calls.append(
call(conf, horizon_utils.CONFIG_FILES[conf]['hook_contexts']))
configs.register.assert_has_calls(calls)
@patch('shutil.rmtree')
@patch('os.path.exists')
@patch.object(horizon_utils.policyd, 'remove_policy_success_file')
@patch.object(horizon_utils.policyd, 'policyd_dir_for')
@patch.object(horizon_utils.policyd,
'is_policyd_override_valid_on_this_release')
def test_maybe_handle_policyd_override_config_false(
self,
mock_valid,
mock_policyd_dir_for,
mock_remove_policy_success_file,
mock_os_path_exists,
mock_shutils_rmtree,
):
self.test_config.set('use-policyd-override', False)
mock_valid.return_value = True
mock_policyd_dir_for.return_value = 'a_dir'
mock_os_path_exists.return_value = True
horizon_utils.maybe_handle_policyd_override(
'a_release', 'config-changed')
mock_policyd_dir_for.assert_called_once_with('openstack-dashboard')
mock_shutils_rmtree.assert_called_once_with('a_dir')
mock_remove_policy_success_file.assert_called_once_with()
@patch.object(horizon_utils.policyd, 'get_policy_resource_filename')
@patch.object(horizon_utils.policyd, 'is_policy_success_file_set')
@patch.object(horizon_utils.policyd,
'is_policyd_override_valid_on_this_release')
def test_maybe_handle_policyd_override_config_changed_done(
self,
mock_valid,
mock_is_policy_success_file_set,
mock_get_policy_resource_filename,
):
self.test_config.set('use-policyd-override', True)
mock_valid.return_value = True
mock_is_policy_success_file_set.return_value = True
horizon_utils.maybe_handle_policyd_override(
'a_release', 'config-changed')
# test that the function bailed before getting to the resource file get
mock_get_policy_resource_filename.assert_not_called()
@patch.object(horizon_utils, 'service')
@patch.object(horizon_utils, 'copy_conf_to_policyd')
@patch.object(horizon_utils, 'blacklist_policyd_paths')
@patch.object(horizon_utils.policyd, 'process_policy_resource_file')
@patch.object(horizon_utils.policyd, 'get_policy_resource_filename')
@patch.object(horizon_utils.policyd, 'is_policy_success_file_set')
@patch.object(horizon_utils.policyd,
'is_policyd_override_valid_on_this_release')
def test_maybe_handle_policyd_override_config_changed_full_run(
self,
mock_valid,
mock_is_policy_success_file_set,
mock_get_policy_resource_filename,
mock_process_policy_resource_file,
mock_blacklist_policyd_paths,
mock_copy_conf_to_policyd,
mock_service,
):
self.test_config.set('use-policyd-override', True)
mock_valid.return_value = True
mock_is_policy_success_file_set.return_value = False
mock_get_policy_resource_filename.return_value = "resource-file"
mock_blacklist_policyd_paths.return_value = ['a-path']
# test no restart
mock_process_policy_resource_file.return_value = False
horizon_utils.maybe_handle_policyd_override(
'a_release', 'config-changed')
mock_get_policy_resource_filename.assert_called_once_with()
mock_process_policy_resource_file.assert_called_once_with(
'resource-file',
'openstack-dashboard',
blacklist_paths=['a-path'],
preserve_topdir=True,
preprocess_filename=horizon_utils.policyd_preprocess_name,
user='horizon',
group='horizon')
mock_copy_conf_to_policyd.assert_called_once_with()
mock_service.assert_not_called()
# test with restart
mock_process_policy_resource_file.return_value = True
horizon_utils.maybe_handle_policyd_override(
'a_release', 'config-changed')
mock_service.assert_has_calls([call('stop', 'apache2'),
call('start', 'apache2')])
@patch.object(horizon_utils, 'DASHBOARD_PKG_DIR', new='/some/dir')
@patch('os.walk')
@patch.object(horizon_utils.policyd, 'policyd_dir_for')
def test_blacklist_policyd_paths(self, mock_policyd_dir_for, mock_os_walk):
mock_policyd_dir_for.return_value = '/etc'
# Note '/some/dir' below has to match the patch on DASHBOAD_PKG_DIR
# above.
mock_os_walk.return_value = [
('/some/dir/conf', ['a-dir'], ['file1']),
('/some/dir/conf/a-dir', [], ['file2'])]
paths = horizon_utils.blacklist_policyd_paths()
mock_policyd_dir_for.assert_called_once_with('openstack-dashboard')
self.assertEqual(paths, ['/etc/file1', '/etc/a-dir/file2'])
@patch.object(horizon_utils, 'DASHBOARD_PKG_DIR', new='/some/dir')
@patch.object(horizon_utils, 'mkdir')
@patch.object(horizon_utils, 'write_file')
@patch('os.path.exists')
@patch('os.walk')
@patch.object(horizon_utils.policyd, 'policyd_dir_for')
def test_copy_conf_to_policyd(
self,
mock_policyd_dir_for,
mock_os_walk,
mock_os_path_exists,
mock_write_file,
mock_mkdir,
):
mock_policyd_dir_for.return_value = '/etc'
# Note '/some/dir' below has to match the patch on DASHBOAD_PKG_DIR
# above.
mock_os_walk.return_value = [
('/some/dir/conf', ['a-dir'], ['file1']),
('/some/dir/conf/a-dir', [], ['file2'])]
mock_os_path_exists.return_value = False
with patch_open() as (_open, _file):
_file.read.side_effect = ['content1', 'content2']
horizon_utils.copy_conf_to_policyd()
mock_mkdir.assert_called_once_with(
'/etc/a-dir', owner='horizon', group='horizon', perms=0o775)
_open.assert_has_calls([
call('/some/dir/conf/file1', 'r'),
call('/some/dir/conf/a-dir/file2', 'r')])
mock_write_file.assert_has_calls([
call('/etc/file1', 'content1', 'horizon', 'horizon'),
call('/etc/a-dir/file2', 'content2', 'horizon', 'horizon')])
@patch.object(horizon_utils, 'POLICYD_HORIZON_SERVICE_TO_DIR',
new={'a': 'a-dir', 'b': 'b-dir', 'c': 'c-dir'})
@patch('os.walk')
@patch.object(horizon_utils.policyd, 'policyd_dir_for')
def test_read_policyd_dirs(
self,
mock_policyd_dir_for,
mock_os_walk,
):
mock_policyd_dir_for.return_value = '/etc'
# Note '/some/dir' below has to match the patch on DASHBOAD_PKG_DIR
# above.
mock_os_walk.return_value = [
('/some/dir/conf', ['b-dir'], ['file1']),
('/some/dir/conf/b-dir', [], ['file2'])]
self.assertEqual(horizon_utils.read_policyd_dirs(), {'b': ['b-dir']})
@patch.object(horizon_utils, 'POLICYD_HORIZON_SERVICE_TO_DIR',
new={'a': 'a-dir', 'b': 'b-dir', 'c': 'c-dir'})
def test_policyd_preprocess_name(self):
# test with no separator
with self.assertRaises(horizon_utils.policyd.BadPolicyYamlFile):
horizon_utils.policyd_preprocess_name("a-name")
# test unrecognised service
with self.assertRaises(horizon_utils.policyd.BadPolicyYamlFile):
horizon_utils.policyd_preprocess_name("d/a-name")
# finally check that the appropriate change is made
self.assertEqual(horizon_utils.policyd_preprocess_name('b/name'),
"b-dir/name")
def test_assess_status(self):
with patch.object(horizon_utils, 'assess_status_func') as asf:
callee = MagicMock()
asf.return_value = callee
horizon_utils.assess_status('test-config')
asf.assert_called_once_with('test-config')
callee.assert_called_once_with()
self.os_application_version_set.assert_called_with(
horizon_utils.VERSION_PACKAGE
)
@patch.object(horizon_utils.ch_cluster, 'get_managed_services_and_ports')
@patch.object(horizon_utils, 'REQUIRED_INTERFACES')
@patch.object(horizon_utils, 'services')
@patch.object(horizon_utils, 'make_assess_status_func')
def test_assess_status_func(self,
make_assess_status_func,
services,
REQUIRED_INTERFACES,
get_managed_services_and_ports):
get_managed_services_and_ports.return_value = (['s1'], [])
services.return_value = ['s1']
horizon_utils.assess_status_func('test-config')
# ports=None whilst port checks are disabled.
make_assess_status_func.assert_called_once_with(
'test-config', REQUIRED_INTERFACES, services=['s1'], ports=None)
def test_pause_unit_helper(self):
with patch.object(horizon_utils, '_pause_resume_helper') as prh:
horizon_utils.pause_unit_helper('random-config')
prh.assert_called_once_with(horizon_utils.pause_unit,
'random-config')
with patch.object(horizon_utils, '_pause_resume_helper') as prh:
horizon_utils.resume_unit_helper('random-config')
prh.assert_called_once_with(horizon_utils.resume_unit,
'random-config')
@patch.object(horizon_utils.ch_cluster, 'get_managed_services_and_ports')
@patch.object(horizon_utils, 'services')
def test_pause_resume_helper(self, services,
get_managed_services_and_ports):
get_managed_services_and_ports.return_value = (['s1'], [])
f = MagicMock()
services.return_value = ['s1']
with patch.object(horizon_utils, 'assess_status_func') as asf:
asf.return_value = 'assessor'
horizon_utils._pause_resume_helper(f, 'some-config')
asf.assert_called_once_with('some-config')
# ports=None whilst port checks are disabled.
f.assert_called_once_with('assessor', services=['s1'], ports=None)
@patch('subprocess.check_call')
def test_db_migration(self, mock_subprocess):
self.cmp_pkgrevno.return_value = -1
horizon_utils.os_release.return_value = 'mitaka'
horizon_utils.db_migration()
mock_subprocess.assert_called_with(
['python2', '/usr/share/openstack-dashboard/manage.py',
'syncdb', '--noinput'])
@patch('subprocess.check_call')
def test_db_migration_bionic_and_beyond_queens(self, mock_subprocess):
self.cmp_pkgrevno.return_value = 0
horizon_utils.os_release.return_value = 'queens'
horizon_utils.db_migration()
mock_subprocess.assert_called_with(
['python2', '/usr/share/openstack-dashboard/manage.py',
'migrate', '--noinput'])
@patch('subprocess.check_call')
def test_db_migration_bionic_and_beyond_rocky(self, mock_subprocess):
self.cmp_pkgrevno.return_value = 0
horizon_utils.os_release.return_value = 'rocky'
horizon_utils.db_migration()
mock_subprocess.assert_called_with(
['python3', '/usr/share/openstack-dashboard/manage.py',
'migrate', '--noinput'])