blob: 17cebcb9925aa1eec25598be3ab7357f0b9dbe35 [file] [log] [blame]
Dennis Dmitriev6f59add2016-10-18 13:45:27 +03001# Copyright 2016 Mirantis, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# 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, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020014import datetime
15import json
16
17from junit_xml import TestSuite, TestCase
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030018
19from tcp_tests import logger
20from tcp_tests import settings
21
22
23LOG = logger.logger
24
25
26class RallyManager(object):
27 """docstring for RallyManager"""
28
29 image_name = 'rallyforge/rally'
Oleksiy Butenkod7045a12016-11-04 13:26:56 +020030 image_version = '0.7.0'
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030031
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020032 def __init__(self, underlay, admin_host):
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030033 super(RallyManager, self).__init__()
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020034 self._admin_host = admin_host
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030035 self._underlay = underlay
36
37 def prepare(self):
38 content = """
39sed -i 's|#swift_operator_role = Member|swift_operator_role=SwiftOperator|g' /etc/rally/rally.conf # noqa
40source /home/rally/openrc
41rally-manage db recreate
42rally deployment create --fromenv --name=tempest
43rally verify install
44rally verify genconfig
45rally verify showconfig"""
46 cmd = "cat > {path} << EOF\n{content}\nEOF".format(
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020047 path='/root/rally/install_tempest.sh', content=content)
48 cmd1 = "chmod +x /root/rally/install_tempest.sh"
Oleksiy Butenkod7045a12016-11-04 13:26:56 +020049 cmd2 = "scp ctl01:/root/keystonercv3 /root/rally/openrc"
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030050
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020051 with self._underlay.remote(host=self._admin_host) as remote:
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030052 LOG.info("Create rally workdir")
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020053 remote.check_call('mkdir -p /root/rally')
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030054 LOG.info("Create install_tempest.sh")
55 remote.check_call(cmd)
56 LOG.info("Chmod +x install_tempest.sh")
57 remote.check_call(cmd1)
58 LOG.info("Copy openstackrc")
59 remote.check_call(cmd2)
60
61 def pull_image(self, version=None):
62 version = version or self.image_version
63 image = self.image_name
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020064 cmd = ("apt-get -y install docker.io &&"
65 " docker pull {image}:{version}".format(image=image,
66 version=version))
67 with self._underlay.remote(host=self._admin_host) as remote:
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030068 LOG.info("Pull {image}:{version}".format(image=image,
69 version=version))
70 remote.check_call(cmd)
71
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020072 with self._underlay.remote(host=self._admin_host) as remote:
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030073 LOG.info("Getting image id")
Oleksiy Butenkod7045a12016-11-04 13:26:56 +020074 cmd = "docker images | grep 0.7.0| awk '{print $3}'"
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030075 res = remote.check_call(cmd)
76 self.image_id = res['stdout'][0].strip()
77 LOG.info("Image ID is {}".format(self.image_id))
78
79 def run(self):
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020080 with self._underlay.remote(host=self._admin_host) as remote:
81 cmd = ("docker run --net host -v /root/rally:/home/rally "
82 "-tid -u root {image_id}".format(image_id=self.image_id))
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030083 LOG.info("Run Rally container")
84 remote.check_call(cmd)
85
86 cmd = ("docker ps | grep {image_id} | "
87 "awk '{{print $1}}'| head -1").format(
88 image_id=self.image_id)
89 LOG.info("Getting container id")
90 res = remote.check_call(cmd)
91 self.docker_id = res['stdout'][0].strip()
92 LOG.info("Container ID is {}".format(self.docker_id))
93
94 def run_tempest(self, test=''):
Oleksiy Butenkod7045a12016-11-04 13:26:56 +020095 docker_exec = ('docker exec -i {docker_id} bash -c "{cmd}"')
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030096 commands = [
97 docker_exec.format(cmd="./install_tempest.sh",
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030098 docker_id=self.docker_id),
99 docker_exec.format(
100 cmd="source /home/rally/openrc && "
101 "rally verify start {test}".format(test=test),
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300102 docker_id=self.docker_id),
103 docker_exec.format(
104 cmd="rally verify results --json --output-file result.json",
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300105 docker_id=self.docker_id),
106 docker_exec.format(
107 cmd="rally verify results --html --output-file result.html",
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300108 docker_id=self.docker_id),
109 ]
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +0200110 with self._underlay.remote(host=self._admin_host) as remote:
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300111 LOG.info("Run tempest inside Rally container")
112 for cmd in commands:
113 remote.check_call(cmd, verbose=True)
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +0200114
115 def get_results(self, store=True, store_file='tempest.xml'):
116 LOG.info('Storing tests results...')
117 res_file_name = 'result.json'
118 file_prefix = 'results_' + datetime.datetime.now().strftime(
119 '%Y%m%d_%H%M%S') + '_'
120 file_dst = '{0}/logs/{1}{2}'.format(
121 settings.LOGS_DIR, file_prefix, res_file_name)
122 with self._underlay.remote(host=self._admin_host) as remote:
123 remote.download(
dis129285a2016-12-05 10:35:14 +0200124 '/root/rally/{0}'.format(res_file_name),
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +0200125 file_dst)
126 res = json.load(remote.open('/root/rally/result.json'))
127 if not store:
128 return res
129
130 formatted_tc = []
131 failed_cases = [res['test_cases'][case]
132 for case in res['test_cases']
133 if res['test_cases'][case]['status']
134 in 'fail']
135 for case in failed_cases:
136 if case:
137 tc = TestCase(case['name'])
138 tc.add_failure_info(case['traceback'])
139 formatted_tc.append(tc)
140
141 skipped_cases = [res['test_cases'][case]
142 for case in res['test_cases']
143 if res['test_cases'][case]['status'] in 'skip']
144 for case in skipped_cases:
145 if case:
146 tc = TestCase(case['name'])
147 tc.add_skipped_info(case['reason'])
148 formatted_tc.append(tc)
149
150 error_cases = [res['test_cases'][case] for case in res['test_cases']
151 if res['test_cases'][case]['status'] in 'error']
152
153 for case in error_cases:
154 if case:
155 tc = TestCase(case['name'])
156 tc.add_error_info(case['traceback'])
157 formatted_tc.append(tc)
158
159 success = [res['test_cases'][case] for case in res['test_cases']
160 if res['test_cases'][case]['status'] in 'success']
161 for case in success:
162 if case:
163 tc = TestCase(case['name'])
164 formatted_tc.append(tc)
165
166 ts = TestSuite("tempest", formatted_tc)
167 with open(store_file, 'w') as f:
168 ts.to_file(f, [ts], prettyprint=False)
169
170 return res