Merge "Add unittest framework for Yardstick API"
[yardstick.git] / yardstick / vTC / apexlake / experimental_framework / deployment_unit.py
1 # Copyright (c) 2015 Intel Research and Development Ireland Ltd.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 from __future__ import absolute_import
16 import os
17 import time
18
19 from experimental_framework import heat_manager
20 from experimental_framework import common
21
22 MAX_RETRY = 3
23
24
25 class DeploymentUnit:
26     """
27     This unit is in charge to manage the deployment of the workloads under
28     test and any other workloads necessary to
29     the benchmark
30     """
31
32     def __init__(self, openstack_credentials):
33         self.heat_manager = heat_manager.HeatManager(openstack_credentials)
34         self.deployed_stacks = list()
35
36     def destroy_heat_template(self, stack_name):
37         """
38         Destroys a stack
39         :param stack_name: Stack of the name to be destroyed (sting)
40         :return: None
41         """
42         try:
43             if self.heat_manager.check_stack_status(stack_name):
44                 if stack_name in self.deployed_stacks:
45                     self.deployed_stacks.remove(stack_name)
46                 self.heat_manager.delete_stack(stack_name)
47
48             status = self.heat_manager.check_stack_status(stack_name)
49             while status and 'DELETE_IN_PROGRESS' in status:
50                 common.LOG.info(status)
51                 time.sleep(5)
52                 status = self.heat_manager.check_stack_status(stack_name)
53             return True
54         except Exception:
55             common.LOG.debug("check_stack_status", exc_info=True)
56             return False
57
58     def destroy_all_deployed_stacks(self):
59         """
60         Destroys all the stacks currently deployed
61         :return: None
62         """
63         for stack in self.deployed_stacks:
64             if self.heat_manager.is_stack_deployed(stack):
65                 self.destroy_heat_template(stack)
66
67     def deploy_heat_template(self, template_file, stack_name, parameters,
68                              attempt=0):
69         """
70         Deploys a heat template and in case of failure retries 3 times
71         :param template_file: full path file name of the heat template
72         :param stack_name: name of the stack to deploy
73         :param parameters: parameters to be given to the heat template
74         :param attempt: number of current attempt
75         :return: returns True in case the creation is completed
76                  returns False in case the creation is failed
77         """
78         if not os.path.isfile(template_file):
79             raise ValueError('The specified file does not exist ("' +
80                              template_file + '")')
81         try:
82             self.heat_manager.create_stack(template_file, stack_name,
83                                            parameters)
84             deployed = True
85         except Exception:
86             common.LOG.debug("create_stack", exc_info=True)
87             deployed = False
88
89         if not deployed and 'COMPLETE' in \
90                 self.heat_manager.check_stack_status(stack_name):
91             try:
92                 self.destroy_heat_template(stack_name)
93             except Exception:
94                 common.LOG.debug("destroy_heat_template", exc_info=True)
95
96         status = self.heat_manager.check_stack_status(stack_name)
97         while status and 'CREATE_IN_PROGRESS' in status:
98             time.sleep(5)
99             status = self.heat_manager.check_stack_status(stack_name)
100         if status and ('FAILED' in status or 'NOT_FOUND' in status):
101             if attempt < MAX_RETRY:
102                 attempt += 1
103                 try:
104                     self.destroy_heat_template(stack_name)
105                 except Exception:
106                     common.LOG.debug("destroy_heat_template", exc_info=True)
107                 return self.deploy_heat_template(template_file, stack_name,
108                                                  parameters, attempt)
109             else:
110                 try:
111                     self.destroy_heat_template(stack_name)
112                 except Exception:
113                     common.LOG.debug("destroy_heat_template", exc_info=True)
114                 finally:
115                     return False
116         if self.heat_manager.check_stack_status(stack_name) and \
117             'COMPLETE' in self.heat_manager.\
118                 check_stack_status(stack_name):
119             self.deployed_stacks.append(stack_name)
120             return True