instack-undercloud/instack_undercloud/tests/test_undercloud.py

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'])