summaryrefslogtreecommitdiff
path: root/watcher_tempest_plugin/tests/scenario/test_execute_basic_optim.py
diff options
context:
space:
mode:
Diffstat (limited to 'watcher_tempest_plugin/tests/scenario/test_execute_basic_optim.py')
-rw-r--r--watcher_tempest_plugin/tests/scenario/test_execute_basic_optim.py191
1 files changed, 0 insertions, 191 deletions
diff --git a/watcher_tempest_plugin/tests/scenario/test_execute_basic_optim.py b/watcher_tempest_plugin/tests/scenario/test_execute_basic_optim.py
deleted file mode 100644
index b4b5e76..0000000
--- a/watcher_tempest_plugin/tests/scenario/test_execute_basic_optim.py
+++ /dev/null
@@ -1,191 +0,0 @@
1# -*- encoding: utf-8 -*-
2# Copyright (c) 2016 b<>com
3#
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14# implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18from __future__ import unicode_literals
19
20import functools
21
22from tempest import config
23from tempest.lib.common.utils import test_utils
24
25from watcher_tempest_plugin.tests.scenario import base
26
27CONF = config.CONF
28
29
30class TestExecuteBasicStrategy(base.BaseInfraOptimScenarioTest):
31 """Tests for action plans"""
32
33 GOAL_NAME = "server_consolidation"
34
35 @classmethod
36 def skip_checks(cls):
37 super(TestExecuteBasicStrategy, cls).skip_checks()
38
39 @classmethod
40 def resource_setup(cls):
41 super(TestExecuteBasicStrategy, cls).resource_setup()
42 if CONF.compute.min_compute_nodes < 2:
43 raise cls.skipException(
44 "Less than 2 compute nodes, skipping multinode tests.")
45 if not CONF.compute_feature_enabled.live_migration:
46 raise cls.skipException("Live migration is not enabled")
47
48 cls.initial_compute_nodes_setup = cls.get_compute_nodes_setup()
49 enabled_compute_nodes = [cn for cn in cls.initial_compute_nodes_setup
50 if cn.get('status') == 'enabled']
51
52 cls.wait_for_compute_node_setup()
53
54 if len(enabled_compute_nodes) < 2:
55 raise cls.skipException(
56 "Less than 2 compute nodes are enabled, "
57 "skipping multinode tests.")
58
59 @classmethod
60 def get_compute_nodes_setup(cls):
61 services_client = cls.mgr.services_client
62 available_services = services_client.list_services()['services']
63
64 return [srv for srv in available_services
65 if srv.get('binary') == 'nova-compute']
66
67 @classmethod
68 def wait_for_compute_node_setup(cls):
69
70 def _are_compute_nodes_setup():
71 try:
72 hypervisors_client = cls.mgr.hypervisor_client
73 hypervisors = hypervisors_client.list_hypervisors(
74 detail=True)['hypervisors']
75 available_hypervisors = set(
76 hyp['hypervisor_hostname'] for hyp in hypervisors)
77 available_services = set(
78 service['host']
79 for service in cls.get_compute_nodes_setup())
80
81 return (
82 available_hypervisors == available_services and
83 len(hypervisors) >= 2)
84 except Exception:
85 return False
86
87 assert test_utils.call_until_true(
88 func=_are_compute_nodes_setup,
89 duration=600,
90 sleep_for=2
91 )
92
93 @classmethod
94 def rollback_compute_nodes_status(cls):
95 current_compute_nodes_setup = cls.get_compute_nodes_setup()
96 for cn_setup in current_compute_nodes_setup:
97 cn_hostname = cn_setup.get('host')
98 matching_cns = [
99 cns for cns in cls.initial_compute_nodes_setup
100 if cns.get('host') == cn_hostname
101 ]
102 initial_cn_setup = matching_cns[0] # Should return a single result
103 if cn_setup.get('status') != initial_cn_setup.get('status'):
104 if initial_cn_setup.get('status') == 'enabled':
105 rollback_func = cls.mgr.services_client.enable_service
106 else:
107 rollback_func = cls.mgr.services_client.disable_service
108 rollback_func(binary='nova-compute', host=cn_hostname)
109
110 def _create_one_instance_per_host(self):
111 """Create 1 instance per compute node
112
113 This goes up to the min_compute_nodes threshold so that things don't
114 get crazy if you have 1000 compute nodes but set min to 3.
115 """
116 host_client = self.mgr.hosts_client
117 all_hosts = host_client.list_hosts()['hosts']
118 compute_nodes = [x for x in all_hosts if x['service'] == 'compute']
119
120 for idx, _ in enumerate(
121 compute_nodes[:CONF.compute.min_compute_nodes], start=1):
122 # by getting to active state here, this means this has
123 # landed on the host in question.
124 self.create_server(
125 name="instance-%d" % idx,
126 image_id=CONF.compute.image_ref,
127 wait_until='ACTIVE',
128 clients=self.mgr)
129
130 def test_execute_basic_action_plan(self):
131 """Execute an action plan based on the BASIC strategy
132
133 - create an audit template with the basic strategy
134 - run the audit to create an action plan
135 - get the action plan
136 - run the action plan
137 - get results and make sure it succeeded
138 """
139 self.addCleanup(self.rollback_compute_nodes_status)
140 self._create_one_instance_per_host()
141
142 _, goal = self.client.show_goal(self.GOAL_NAME)
143 _, strategy = self.client.show_strategy("basic")
144 _, audit_template = self.create_audit_template(
145 goal['uuid'], strategy=strategy['uuid'])
146 _, audit = self.create_audit(audit_template['uuid'])
147
148 try:
149 self.assertTrue(test_utils.call_until_true(
150 func=functools.partial(
151 self.has_audit_finished, audit['uuid']),
152 duration=600,
153 sleep_for=2
154 ))
155 except ValueError:
156 self.fail("The audit has failed!")
157
158 _, finished_audit = self.client.show_audit(audit['uuid'])
159 if finished_audit.get('state') in ('FAILED', 'CANCELLED', 'SUSPENDED'):
160 self.fail("The audit ended in unexpected state: %s!"
161 % finished_audit.get('state'))
162
163 _, action_plans = self.client.list_action_plans(
164 audit_uuid=audit['uuid'])
165 action_plan = action_plans['action_plans'][0]
166
167 _, action_plan = self.client.show_action_plan(action_plan['uuid'])
168
169 if action_plan['state'] in ('SUPERSEDED', 'SUCCEEDED'):
170 # This means the action plan is superseded so we cannot trigger it,
171 # or it is empty.
172 return
173
174 # Execute the action by changing its state to PENDING
175 _, updated_ap = self.client.start_action_plan(action_plan['uuid'])
176
177 self.assertTrue(test_utils.call_until_true(
178 func=functools.partial(
179 self.has_action_plan_finished, action_plan['uuid']),
180 duration=600,
181 sleep_for=2
182 ))
183 _, finished_ap = self.client.show_action_plan(action_plan['uuid'])
184 _, action_list = self.client.list_actions(
185 action_plan_uuid=finished_ap["uuid"])
186
187 self.assertIn(updated_ap['state'], ('PENDING', 'ONGOING'))
188 self.assertIn(finished_ap['state'], ('SUCCEEDED', 'SUPERSEDED'))
189
190 for action in action_list['actions']:
191 self.assertEqual('SUCCEEDED', action.get('state'))