Implement wait_for_stack_ready

This is used to block until a stack returns a completed status, a failed
status, or times out.

Change-Id: Ia7d45331dd4dbdb5ac522eeedfba53bfa848d182
This commit is contained in:
Brad P. Crochet 2015-04-15 12:27:58 -04:00 committed by Dougal Matthews
parent f32c98501f
commit bb804c6ce8
3 changed files with 166 additions and 55 deletions

View File

@ -1,55 +0,0 @@
# 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.
#
from unittest import TestCase
import mock
from rdomanager_oscplugin import utils
class TestPasswordsUtil(TestCase):
def test_generate_passwords(self):
passwords = utils.generate_overcloud_passwords()
passwords2 = utils.generate_overcloud_passwords()
self.assertEqual(len(passwords), 13)
self.assertNotEqual(passwords, passwords2)
def test_check_hypervisor_stats(self):
mock_compute = mock.Mock()
mock_stats = mock.Mock()
return_values = [
{'count': 0, 'memory_mb': 0, 'vcpus': 0},
{'count': 1, 'memory_mb': 1, 'vcpus': 1},
]
mock_stats.to_dict.side_effect = return_values
mock_compute.hypervisors.statistics.return_value = mock_stats
stats = utils.check_hypervisor_stats(
mock_compute, nodes=1, memory=1, vcpu=1)
self.assertEqual(stats, None)
self.assertEqual(mock_stats.to_dict.call_count, 1)
stats = utils.check_hypervisor_stats(
mock_compute, nodes=1, memory=1, vcpu=1)
self.assertEqual(stats, return_values[-1])
self.assertEqual(mock_stats.to_dict.call_count, 2)

View File

@ -0,0 +1,124 @@
# 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.
#
from unittest import TestCase
import mock
from rdomanager_oscplugin import utils
class TestPasswordsUtil(TestCase):
def test_generate_passwords(self):
passwords = utils.generate_overcloud_passwords()
passwords2 = utils.generate_overcloud_passwords()
self.assertEqual(len(passwords), 13)
self.assertNotEqual(passwords, passwords2)
class TestCheckHypervisorUtil(TestCase):
def test_check_hypervisor_stats(self):
mock_compute = mock.Mock()
mock_stats = mock.Mock()
return_values = [
{'count': 0, 'memory_mb': 0, 'vcpus': 0},
{'count': 1, 'memory_mb': 1, 'vcpus': 1},
]
mock_stats.to_dict.side_effect = return_values
mock_compute.hypervisors.statistics.return_value = mock_stats
stats = utils.check_hypervisor_stats(
mock_compute, nodes=1, memory=1, vcpu=1)
self.assertEqual(stats, None)
self.assertEqual(mock_stats.to_dict.call_count, 1)
stats = utils.check_hypervisor_stats(
mock_compute, nodes=1, memory=1, vcpu=1)
self.assertEqual(stats, return_values[-1])
self.assertEqual(mock_stats.to_dict.call_count, 2)
class TestWaitForStackUtil(TestCase):
def setUp(self):
self.mock_orchestration = mock.Mock()
self.mock_stacks = mock.MagicMock()
self.stack_status = mock.PropertyMock()
type(self.mock_stacks).stack_status = self.stack_status
self.mock_orchestration.stacks.get.return_value = self.mock_stacks
def test_wait_for_stack_ready(self):
self.mock_orchestration.reset_mock()
self.mock_stacks.reset_mock()
return_values = [
'CREATE_COMPLETE'
]
self.stack_status.side_effect = return_values
complete = utils.wait_for_stack_ready(self.mock_orchestration, 'stack')
self.assertEqual(complete, True)
def test_wait_for_stack_ready_no_stack(self):
self.mock_orchestration.reset_mock()
self.mock_orchestration.stacks.get.return_value = None
complete = utils.wait_for_stack_ready(self.mock_orchestration, 'stack')
self.mock_orchestration.stacks.get.return_value = self.mock_stacks
self.assertEqual(complete, False)
def test_wait_for_stack_ready_failed(self):
self.mock_orchestration.reset_mock()
self.mock_stacks.reset_mock()
return_values = [
'CREATE_FAILED'
]
self.stack_status.side_effect = return_values
complete = utils.wait_for_stack_ready(self.mock_orchestration, 'stack')
self.assertEqual(complete, False)
def test_wait_for_stack_ready_timeout(self):
self.mock_orchestration.reset_mock()
self.mock_stacks.reset_mock()
return_values = [
mock.Mock(stack_status='CREATE_RUNNING'),
mock.Mock(stack_status='CREATE_RUNNING'),
mock.Mock(stack_status='CREATE_RUNNING'),
mock.Mock(stack_status='CREATE_RUNNING'),
mock.Mock(stack_status='CREATE_COMPLETE')
]
# self.stack_status.side_effect = return_values
self.mock_orchestration.stacks.get.side_effect = return_values
complete = utils.wait_for_stack_ready(
self.mock_orchestration, 'stack', loops=4, sleep=0.1)
self.assertEqual(complete, False)

View File

@ -14,7 +14,9 @@
#
import hashlib
import re
import six
import time
import uuid
@ -78,3 +80,43 @@ def check_hypervisor_stats(compute_client, nodes=1, memory=0, vcpu=0):
return statistics
else:
return None
def wait_for_stack_ready(
orchestration_client, stack_name, loops=220, sleep=10):
"""Check the status of an orchestration stack
Get the status of an orchestration stack and check whether it is complete
or failed.
:param orchestration_client: Instance of Orchestration client
:type orchestration_client: heatclient.v1.client.Client
:param stack_name: Name or UUID of stack to retrieve
:type stack_name: string
:param loops: How many times to loop
:type loops: int
:param sleep: How long to sleep between loops
:type sleep: int
"""
SUCCESSFUL_MATCH_OUTPUT = "(CREATE|UPDATE)_COMPLETE"
FAIL_MATCH_OUTPUT = "(CREATE|UPDATE)_FAILED"
for _ in range(0, loops):
stack = orchestration_client.stacks.get(stack_name)
if not stack:
return False
status = stack.stack_status
if re.match(SUCCESSFUL_MATCH_OUTPUT, status):
return True
if re.match(FAIL_MATCH_OUTPUT, status):
return False
time.sleep(sleep)
return False