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

138 lines
4.8 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 bunch
import fixtures
import mock
from muranoagent.common import config as cfg
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
CONF = cfg.CONF
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('__builtin__.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('__builtin__.open')
def test_configure_puppet(self, open_mock):
self._open_mock(open_mock)
self.puppet_executor._configure_puppet()
@mock.patch('subprocess.Popen')
@mock.patch('__builtin__.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
self.puppet_executor.load('path',
template['Scripts'].values()[0]['Options'])
self.puppet_executor.run('test')
@mock.patch('subprocess.Popen')
@mock.patch('__builtin__.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
self.puppet_executor.load('path',
template['Scripts'].values()[0]['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=[]):
class FakeUUID(object):
def __init__(self, v):
self.hex = v
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 + ':}}'