murano-agent/muranoagent/tests/unit/executors/test_puppet.py

140 lines
4.9 KiB
Python

# Copyright (c) 2015 Telefonica I+D
#
# 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 fixtures
import mock
from muranoagent import bunch
from muranoagent import exceptions as ex
from muranoagent.executors import puppet
from muranoagent.tests.unit import base
from muranoagent.tests.unit import execution_plan as ep
class TestPuppetExecutor(base.MuranoAgentTestCase, fixtures.TestWithFixtures):
def setUp(self):
super(TestPuppetExecutor, self).setUp()
self.puppet_executor = puppet.PuppetExecutor('module::recipe')
def test_create_manifest(self):
node = self.puppet_executor._create_manifest('cookbook', 'recipe')
self.assertEqual(node, self.get_manifest('cookbook', 'recipe'))
def test_create_manifest_norecipe(self):
node = self.puppet_executor._create_manifest('cookbook', '')
self.assertEqual(node, self.get_manifest_norecipe('cookbook'))
def test_create_hierdata(self):
atts = {
'att1': 'value1',
'att2': 'value2'
}
node = self.puppet_executor._create_hiera_data('cookbook', atts)
self.assertEqual(node, self.get_hieradata())
@mock.patch('six.moves.builtins.open')
def test_generate_files(self, open_mock):
self._open_mock(open_mock)
atts = {
'att1': 'value1',
'att2': 'value2'
}
self.puppet_executor._generate_files('cookbook', 'recipe', atts)
@mock.patch('six.moves.builtins.open')
def test_configure_puppet(self, open_mock):
self._open_mock(open_mock)
self.puppet_executor._configure_puppet()
@mock.patch('subprocess.Popen')
@mock.patch('six.moves.builtins.open')
def test_module(self, open_mock, mock_subproc_popen):
#
# setup
#
self._open_mock(open_mock)
process_mock = mock.Mock()
attrs = {'communicate.return_value': ('ouput', 'ok'),
'poll.return_value': 0}
process_mock.configure_mock(**attrs)
mock_subproc_popen.return_value = process_mock
template = self.useFixture(ep.PuppetExPlanDownloable()).execution_plan
script = list(template['Scripts'].values())[0]
self.puppet_executor.load('path',
script['Options'])
self.puppet_executor.run('test')
@mock.patch('subprocess.Popen')
@mock.patch('six.moves.builtins.open')
def test_module_error(self, open_mock, mock_subproc_popen):
#
# setup
#
self._open_mock(open_mock)
process_mock = mock.Mock()
attrs = {'communicate.return_value': ('ouput', 'error'),
'poll.return_value': 2}
process_mock.configure_mock(**attrs)
mock_subproc_popen.return_value = process_mock
template = self.useFixture(ep.PuppetExPlanDownloable()).execution_plan
script = list(template['Scripts'].values())[0]
self.puppet_executor.load('path',
script['Options'])
self.assertRaises(ex.CustomException, self.puppet_executor.run,
'test')
def test_puppet_module_wrong(self):
puppet_executor = puppet.PuppetExecutor('wrong')
self.assertRaises(ex.CustomException, puppet_executor.run,
'test')
def _stub_uuid(self, values=None):
class FakeUUID(object):
def __init__(self, v):
self.hex = v
if values is None:
values = []
mock_uuid4 = mock.patch('uuid.uuid4').start()
mock_uuid4.side_effect = [FakeUUID(v) for v in values]
return mock_uuid4
def _open_mock(self, open_mock):
context_manager_mock = mock.Mock()
open_mock.return_value = context_manager_mock
file_mock = mock.Mock()
file_mock.read.return_value = ''
enter_mock = mock.Mock()
enter_mock.return_value = file_mock
exit_mock = mock.Mock()
setattr(context_manager_mock, '__enter__', enter_mock)
setattr(context_manager_mock, '__exit__', exit_mock)
def get_hieradata(self):
return {'cookbook::att1': 'value1', 'cookbook::att2': 'value2'}
def get_manifest(self, cookbook, recipe):
return "node \'default\' { " \
"class { " + cookbook + '::' + recipe + ':}}'
def get_manifest_norecipe(self, cookbook):
return "node \'default\' { " \
"class { " + cookbook + ':}}'