201 lines
9.3 KiB
Python
201 lines
9.3 KiB
Python
# Copyright 2015 Red Hat 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.
|
|
|
|
import io
|
|
import os
|
|
import tempfile
|
|
|
|
import fixtures
|
|
import mock
|
|
from oslotest import base
|
|
from oslotest import mockpatch
|
|
|
|
from instack_undercloud import undercloud
|
|
|
|
# TODO(bnemec): Test all the things
|
|
# TODO(bnemec): Stop the code from logging to the real log file during tests
|
|
|
|
|
|
class TestUndercloud(base.BaseTestCase):
|
|
@mock.patch('instack_undercloud.undercloud._check_hostname')
|
|
@mock.patch('instack_undercloud.undercloud._run_command')
|
|
@mock.patch('instack_undercloud.undercloud._configure_ssh_keys')
|
|
@mock.patch('instack_undercloud.undercloud._run_orc')
|
|
@mock.patch('instack_undercloud.undercloud._run_instack')
|
|
@mock.patch('instack_undercloud.undercloud._generate_environment')
|
|
@mock.patch('instack_undercloud.undercloud._load_config')
|
|
def test_install(self, mock_load_config, mock_generate_environment,
|
|
mock_run_instack, mock_run_orc, mock_configure_ssh_keys,
|
|
mock_run_command, mock_check_hostname):
|
|
fake_env = mock.MagicMock()
|
|
mock_generate_environment.return_value = fake_env
|
|
undercloud.install('.')
|
|
mock_generate_environment.assert_called_with('.')
|
|
mock_run_instack.assert_called_with(fake_env)
|
|
mock_run_orc.assert_called_with(fake_env)
|
|
mock_run_command.assert_called_with(
|
|
['sudo', 'rm', '-f', '/tmp/svc-map-services'], None, 'rm')
|
|
|
|
def test_generate_password(self):
|
|
first = undercloud._generate_password()
|
|
second = undercloud._generate_password()
|
|
self.assertNotEqual(first, second)
|
|
|
|
|
|
class TestCheckHostname(base.BaseTestCase):
|
|
@mock.patch('instack_undercloud.undercloud._run_command')
|
|
def test_correct(self, mock_run_command):
|
|
mock_run_command.side_effect = ['test-hostname', 'test-hostname']
|
|
self.useFixture(fixtures.EnvironmentVariable('HOSTNAME',
|
|
'test-hostname'))
|
|
fake_hosts = io.StringIO(u'127.0.0.1 test-hostname\n')
|
|
with mock.patch('instack_undercloud.undercloud.open',
|
|
return_value=fake_hosts, create=True):
|
|
undercloud._check_hostname()
|
|
|
|
@mock.patch('instack_undercloud.undercloud._run_command')
|
|
def test_static_transient_mismatch(self, mock_run_command):
|
|
mock_run_command.side_effect = ['test-hostname', 'other-hostname']
|
|
self.useFixture(fixtures.EnvironmentVariable('HOSTNAME',
|
|
'test-hostname'))
|
|
fake_hosts = io.StringIO(u'127.0.0.1 test-hostname\n')
|
|
with mock.patch('instack_undercloud.undercloud.open',
|
|
return_value=fake_hosts, create=True):
|
|
self.assertRaises(RuntimeError, undercloud._check_hostname)
|
|
|
|
@mock.patch('instack_undercloud.undercloud._run_command')
|
|
def test_missing_entry(self, mock_run_command):
|
|
mock_run_command.side_effect = ['test-hostname', 'test-hostname']
|
|
self.useFixture(fixtures.EnvironmentVariable('HOSTNAME',
|
|
'test-hostname'))
|
|
fake_hosts = io.StringIO(u'127.0.0.1 other-hostname\n')
|
|
with mock.patch('instack_undercloud.undercloud.open',
|
|
return_value=fake_hosts, create=True):
|
|
self.assertRaises(RuntimeError, undercloud._check_hostname)
|
|
|
|
@mock.patch('instack_undercloud.undercloud._run_command')
|
|
def test_no_substring_match(self, mock_run_command):
|
|
mock_run_command.side_effect = ['test-hostname', 'test-hostname']
|
|
self.useFixture(fixtures.EnvironmentVariable('HOSTNAME',
|
|
'test-hostname'))
|
|
fake_hosts = io.StringIO(u'127.0.0.1 test-hostname-bad\n')
|
|
with mock.patch('instack_undercloud.undercloud.open',
|
|
return_value=fake_hosts, create=True):
|
|
self.assertRaises(RuntimeError, undercloud._check_hostname)
|
|
|
|
@mock.patch('instack_undercloud.undercloud._run_command')
|
|
def test_commented(self, mock_run_command):
|
|
mock_run_command.side_effect = ['test-hostname', 'test-hostname']
|
|
self.useFixture(fixtures.EnvironmentVariable('HOSTNAME',
|
|
'test-hostname'))
|
|
fake_hosts = io.StringIO(u""" #127.0.0.1 test-hostname\n
|
|
127.0.0.1 other-hostname\n""")
|
|
with mock.patch('instack_undercloud.undercloud.open',
|
|
return_value=fake_hosts, create=True):
|
|
self.assertRaises(RuntimeError, undercloud._check_hostname)
|
|
|
|
|
|
class TestGenerateEnvironment(base.BaseTestCase):
|
|
def setUp(self):
|
|
super(TestGenerateEnvironment, self).setUp()
|
|
# Things that need to always be mocked out, but that the tests
|
|
# don't want to care about.
|
|
self.useFixture(mockpatch.Patch(
|
|
'instack_undercloud.undercloud._write_password_file'))
|
|
self.useFixture(mockpatch.Patch(
|
|
'instack_undercloud.undercloud._load_config'))
|
|
mock_isdir = mockpatch.Patch('os.path.isdir')
|
|
self.useFixture(mock_isdir)
|
|
mock_isdir.mock.return_value = False
|
|
# Some tests do care about this, but they can override the default
|
|
# return value, and then the tests that don't care can ignore it.
|
|
self.mock_distro = mockpatch.Patch('platform.linux_distribution')
|
|
self.useFixture(self.mock_distro)
|
|
self.mock_distro.mock.return_value = [
|
|
'Red Hat Enterprise Linux Server 7.1']
|
|
|
|
@mock.patch('socket.gethostname')
|
|
def test_hostname_set(self, mock_gethostname):
|
|
fake_hostname = 'crazy-test-hostname-!@#$%12345'
|
|
mock_gethostname.return_value = fake_hostname
|
|
env = undercloud._generate_environment('.')
|
|
self.assertEqual(fake_hostname, env['HOSTNAME'])
|
|
|
|
def test_elements_path_input(self):
|
|
test_path = '/test/elements/path'
|
|
self.useFixture(fixtures.EnvironmentVariable('ELEMENTS_PATH',
|
|
test_path))
|
|
env = undercloud._generate_environment('.')
|
|
self.assertEqual(test_path, env['ELEMENTS_PATH'])
|
|
|
|
def test_default_elements_path(self):
|
|
env = undercloud._generate_environment('.')
|
|
test_path = ('%s:%s:/usr/share/tripleo-image-elements:'
|
|
'/usr/share/diskimage-builder/elements' %
|
|
(os.path.join(os.getcwd(), 'tripleo-puppet-elements',
|
|
'elements'),
|
|
'./elements'))
|
|
self.assertEqual(test_path, env['ELEMENTS_PATH'])
|
|
|
|
def test_rhel7_distro(self):
|
|
self.useFixture(fixtures.EnvironmentVariable('NODE_DIST', None))
|
|
env = undercloud._generate_environment('.')
|
|
self.assertEqual('rhel7', env['NODE_DIST'])
|
|
self.assertEqual('./json-files/rhel-7-undercloud-packages.json',
|
|
env['JSONFILE'])
|
|
self.assertEqual('disable', env['REG_METHOD'])
|
|
self.assertEqual('1', env['REG_HALT_UNREGISTER'])
|
|
|
|
def test_centos7_distro(self):
|
|
self.useFixture(fixtures.EnvironmentVariable('NODE_DIST', None))
|
|
self.mock_distro.mock.return_value = ['CentOS Linux release 7.1']
|
|
env = undercloud._generate_environment('.')
|
|
self.assertEqual('centos7', env['NODE_DIST'])
|
|
self.assertEqual('./json-files/centos-7-undercloud-packages.json',
|
|
env['JSONFILE'])
|
|
|
|
def test_fedora_distro(self):
|
|
self.useFixture(fixtures.EnvironmentVariable('NODE_DIST', None))
|
|
self.mock_distro.mock.return_value = ['Fedora Infinity + 1']
|
|
self.assertRaises(RuntimeError, undercloud._generate_environment, '.')
|
|
|
|
def test_other_distro(self):
|
|
self.useFixture(fixtures.EnvironmentVariable('NODE_DIST', None))
|
|
self.mock_distro.mock.return_value = ['Gentoo']
|
|
self.assertRaises(RuntimeError, undercloud._generate_environment, '.')
|
|
|
|
def test_opts_in_env(self):
|
|
env = undercloud._generate_environment('.')
|
|
# Just spot check, we don't want to replicate the entire opt list here
|
|
self.assertEqual(env['DEPLOYMENT_MODE'], 'poc')
|
|
self.assertEqual(env['DISCOVERY_RUNBENCH'], '0')
|
|
self.assertEqual('192.0.2.1/24', env['PUBLIC_INTERFACE_IP'])
|
|
self.assertEqual('192.0.2.1', env['LOCAL_IP'])
|
|
|
|
def test_answers_file_support(self):
|
|
fake_answers = tempfile.mkstemp()[1]
|
|
with open(fake_answers, 'w') as f:
|
|
f.write('DEPLOYMENT_MODE=scale\n')
|
|
# NOTE(bnemec): For some reason, mocking ANSWERS_PATH with a
|
|
# PropertyMock isn't working. This accomplishes the same thing.
|
|
save_path = undercloud.ANSWERS_PATH
|
|
undercloud.ANSWERS_PATH = fake_answers
|
|
|
|
def reset_answers():
|
|
undercloud.ANSWERS_PATH = save_path
|
|
|
|
self.addCleanup(reset_answers)
|
|
env = undercloud._generate_environment('.')
|
|
self.assertEqual('scale', env['DEPLOYMENT_MODE'])
|