Merge "Eliminating a race condition in the export_stack function"
This commit is contained in:
commit
a8ae458af0
|
@ -14,7 +14,6 @@
|
|||
#
|
||||
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
@ -104,17 +103,7 @@ def export_stack(heat, stack, should_filter=False,
|
|||
file = os.path.join(config_download_dir,
|
||||
stack,
|
||||
export_param["file"])
|
||||
|
||||
if not os.path.exists(file):
|
||||
LOG.warning('File %s was not found during export' %
|
||||
file)
|
||||
with open(file, 'r') as parameter_file:
|
||||
try:
|
||||
export_data = json.load(parameter_file)
|
||||
except (TypeError, json.JSONDecodeError) as e:
|
||||
LOG.error(
|
||||
_('Could not read file %s') % file)
|
||||
LOG.error(e)
|
||||
export_data = oooutils.get_parameter_file(file)
|
||||
else:
|
||||
# get stack data
|
||||
export_data = oooutils.get_stack_output_item(
|
||||
|
|
|
@ -75,11 +75,13 @@ class TestExport(TestCase):
|
|||
}
|
||||
self.mock_open_ceph_all = mock.mock_open(read_data=str(ceph_all))
|
||||
|
||||
@mock.patch('tripleoclient.utils.os.path.exists',
|
||||
autospec=True, reutrn_value=True)
|
||||
@mock.patch('tripleoclient.utils.get_stack')
|
||||
def test_export_stack(self, mock_get_stack):
|
||||
def test_export_stack(self, mock_get_stack, mock_exists):
|
||||
heat = mock.Mock()
|
||||
mock_get_stack.return_value = self.mock_stack
|
||||
with mock.patch('six.moves.builtins.open', self.mock_open):
|
||||
with mock.patch('tripleoclient.utils.open', self.mock_open):
|
||||
data = export.export_stack(heat, "overcloud")
|
||||
|
||||
expected = \
|
||||
|
@ -95,8 +97,10 @@ class TestExport(TestCase):
|
|||
'config-download/overcloud/group_vars/overcloud.json'),
|
||||
'r')
|
||||
|
||||
@mock.patch('tripleoclient.utils.os.path.exists',
|
||||
autospec=True, reutrn_value=True)
|
||||
@mock.patch('tripleoclient.utils.get_stack')
|
||||
def test_export_stack_should_filter(self, mock_get_stack):
|
||||
def test_export_stack_should_filter(self, mock_get_stack, mock_exists):
|
||||
heat = mock.Mock()
|
||||
mock_get_stack.return_value = self.mock_stack
|
||||
self.mock_open = mock.mock_open(
|
||||
|
@ -117,29 +121,33 @@ class TestExport(TestCase):
|
|||
'config-download/overcloud/group_vars/overcloud.json'),
|
||||
'r')
|
||||
|
||||
@mock.patch('tripleoclient.utils.os.path.exists',
|
||||
autospec=True, reutrn_value=True)
|
||||
@mock.patch('tripleoclient.utils.get_stack')
|
||||
def test_export_stack_cd_dir(self, mock_get_stack):
|
||||
def test_export_stack_cd_dir(self, mock_get_stack, mock_exists):
|
||||
heat = mock.Mock()
|
||||
mock_get_stack.return_value = self.mock_stack
|
||||
with mock.patch('six.moves.builtins.open', self.mock_open):
|
||||
with mock.patch('tripleoclient.utils.open', self.mock_open):
|
||||
export.export_stack(heat, "overcloud",
|
||||
config_download_dir='/foo')
|
||||
self.mock_open.assert_called_once_with(
|
||||
'/foo/overcloud/group_vars/overcloud.json', 'r')
|
||||
|
||||
@mock.patch('tripleoclient.utils.os.path.exists',
|
||||
autospec=True, reutrn_value=True)
|
||||
@mock.patch('tripleoclient.utils.get_stack')
|
||||
def test_export_stack_stack_name(self, mock_get_stack):
|
||||
def test_export_stack_stack_name(self, mock_get_stack, mock_exists):
|
||||
heat = mock.Mock()
|
||||
mock_get_stack.return_value = self.mock_stack
|
||||
with mock.patch('six.moves.builtins.open', self.mock_open):
|
||||
with mock.patch('tripleoclient.utils.open', self.mock_open):
|
||||
export.export_stack(heat, "control")
|
||||
mock_get_stack.assert_called_once_with(heat, 'control')
|
||||
|
||||
@mock.patch('tripleoclient.export.LOG.error', autospec=True)
|
||||
@mock.patch('tripleoclient.export.json.load', autospec=True,
|
||||
@mock.patch('tripleoclient.utils.LOG.error', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.json.load', autospec=True,
|
||||
side_effect=JSONDecodeError)
|
||||
@mock.patch('tripleoclient.export.open')
|
||||
@mock.patch('tripleoclient.export.os.path.exists', autospec=True,
|
||||
@mock.patch('tripleoclient.utils.open')
|
||||
@mock.patch('tripleoclient.utils.os.path.exists', autospec=True,
|
||||
return_value=True)
|
||||
@mock.patch('tripleoclient.utils.get_stack', autospec=True)
|
||||
def test_export_stack_decode_error(self, mock_get_stack, mock_exists,
|
||||
|
@ -147,7 +155,8 @@ class TestExport(TestCase):
|
|||
|
||||
heat = mock.MagicMock()
|
||||
mock_get_stack.return_value = self.mock_stack
|
||||
export.export_stack(heat, "overcloud")
|
||||
self.assertRaises(
|
||||
RuntimeError, export.export_stack, heat, "overcloud")
|
||||
|
||||
mock_open.assert_called_once_with(
|
||||
os.path.join(
|
||||
|
|
|
@ -26,6 +26,7 @@ import errno
|
|||
import getpass
|
||||
import glob
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
|
||||
import multiprocessing
|
||||
|
@ -3065,3 +3066,25 @@ def parse_container_image_prepare(tht_key='ContainerImagePrepare',
|
|||
else:
|
||||
raise RuntimeError("Unsupported tht_key: %s" % tht_key)
|
||||
return image_map
|
||||
|
||||
|
||||
def get_parameter_file(path):
|
||||
"""Retrieve parameter json file from the supplied path.
|
||||
If the file doesn't exist, or if the decoding fails, log the failure
|
||||
and return `None`.
|
||||
:param path: path to the parameter file
|
||||
:dtype path: `string`
|
||||
"""
|
||||
file_data = None
|
||||
if os.path.exists(path):
|
||||
with open(path, 'r') as parameter_file:
|
||||
try:
|
||||
file_data = json.load(parameter_file)
|
||||
except (TypeError, json.JSONDecodeError) as e:
|
||||
LOG.error(
|
||||
_('Could not read file %s') % path)
|
||||
LOG.error(e)
|
||||
else:
|
||||
LOG.warning('File %s was not found during export' %
|
||||
path)
|
||||
return file_data
|
||||
|
|
Loading…
Reference in New Issue