blob: af3e68d7d936aab36c7286425fdd1f2a596a42b3 [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'
30 image_version = '0.5.0'
31
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"
49 cmd2 = "scp ctl01:/root/keystonerc /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")
74 cmd = "docker images | grep 0.5.0| awk '{print $3}'"
75 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=''):
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +020095 docker_exec = ('source /root/rally/openrc; '
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030096 'docker exec -i {docker_id} bash -c "{cmd}"')
97 commands = [
98 docker_exec.format(cmd="./install_tempest.sh",
Dennis Dmitriev6f59add2016-10-18 13:45:27 +030099 docker_id=self.docker_id),
100 docker_exec.format(
101 cmd="source /home/rally/openrc && "
102 "rally verify start {test}".format(test=test),
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300103 docker_id=self.docker_id),
104 docker_exec.format(
105 cmd="rally verify results --json --output-file result.json",
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300106 docker_id=self.docker_id),
107 docker_exec.format(
108 cmd="rally verify results --html --output-file result.html",
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300109 docker_id=self.docker_id),
110 ]
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +0200111 with self._underlay.remote(host=self._admin_host) as remote:
Dennis Dmitriev6f59add2016-10-18 13:45:27 +0300112 LOG.info("Run tempest inside Rally container")
113 for cmd in commands:
114 remote.check_call(cmd, verbose=True)
Dennis Dmitriev9cc4ca32016-11-03 13:50:45 +0200115
116 def get_results(self, store=True, store_file='tempest.xml'):
117 LOG.info('Storing tests results...')
118 res_file_name = 'result.json'
119 file_prefix = 'results_' + datetime.datetime.now().strftime(
120 '%Y%m%d_%H%M%S') + '_'
121 file_dst = '{0}/logs/{1}{2}'.format(
122 settings.LOGS_DIR, file_prefix, res_file_name)
123 with self._underlay.remote(host=self._admin_host) as remote:
124 remote.download(
125 '/root/rally/{1}'.format(res_file_name),
126 file_dst)
127 res = json.load(remote.open('/root/rally/result.json'))
128 if not store:
129 return res
130
131 formatted_tc = []
132 failed_cases = [res['test_cases'][case]
133 for case in res['test_cases']
134 if res['test_cases'][case]['status']
135 in 'fail']
136 for case in failed_cases:
137 if case:
138 tc = TestCase(case['name'])
139 tc.add_failure_info(case['traceback'])
140 formatted_tc.append(tc)
141
142 skipped_cases = [res['test_cases'][case]
143 for case in res['test_cases']
144 if res['test_cases'][case]['status'] in 'skip']
145 for case in skipped_cases:
146 if case:
147 tc = TestCase(case['name'])
148 tc.add_skipped_info(case['reason'])
149 formatted_tc.append(tc)
150
151 error_cases = [res['test_cases'][case] for case in res['test_cases']
152 if res['test_cases'][case]['status'] in 'error']
153
154 for case in error_cases:
155 if case:
156 tc = TestCase(case['name'])
157 tc.add_error_info(case['traceback'])
158 formatted_tc.append(tc)
159
160 success = [res['test_cases'][case] for case in res['test_cases']
161 if res['test_cases'][case]['status'] in 'success']
162 for case in success:
163 if case:
164 tc = TestCase(case['name'])
165 formatted_tc.append(tc)
166
167 ts = TestSuite("tempest", formatted_tc)
168 with open(store_file, 'w') as f:
169 ts.to_file(f, [ts], prettyprint=False)
170
171 return res