# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2012 IBM Corp. # # 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. import json import os import shutil import sys from oslo.config import cfg from tempest.common.rest_client import RestClient from tempest import config CONF = config.TempestConfig() class CoverageClientJSON(RestClient): def __init__(self, config, username, password, auth_url, tenant_name=None): super(CoverageClientJSON, self).__init__(config, username, password, auth_url, tenant_name) self.service = self.config.compute.catalog_type def start_coverage(self): post_body = { 'start': {}, } post_body = json.dumps(post_body) return self.post('os-coverage/action', post_body, self.headers) def start_coverage_combine(self): post_body = { 'start': { 'combine': True, }, } post_body = json.dumps(post_body) return self.post('os-coverage/action', post_body, self.headers) def stop_coverage(self): post_body = { 'stop': {}, } post_body = json.dumps(post_body) resp, body = self.post('os-coverage/action', post_body, self.headers) body = json.loads(body) return resp, body def report_coverage_xml(self, file=None): post_body = { 'report': { 'file': 'coverage.report', 'xml': True, }, } if file: post_body['report']['file'] = file post_body = json.dumps(post_body) resp, body = self.post('os-coverage/action', post_body, self.headers) body = json.loads(body) return resp, body def report_coverage(self, file=None): post_body = { 'report': { 'file': 'coverage.report', }, } if file: post_body['report']['file'] = file post_body = json.dumps(post_body) resp, body = self.post('os-coverage/action', post_body, self.headers) body = json.loads(body) return resp, body def report_coverage_html(self, file=None): post_body = { 'report': { 'file': 'coverage.report', 'html': True, }, } if file: post_body['report']['file'] = file post_body = json.dumps(post_body) resp, body = self.post('os-coverage/action', post_body, self.headers) body = json.loads(body) return resp, body def parse_opts(argv): cli_opts = [ cfg.StrOpt('command', short='c', default='', help="This required argument is used to specify the " "coverage command to run. Only 'start', " "'stop', or 'report' are valid fields."), cfg.StrOpt('filename', default='tempest-coverage', help="Specify a filename to be used for generated report " "files"), cfg.BoolOpt('xml', default=False, help='Generate XML reports instead of text'), cfg.BoolOpt('html', default=False, help='Generate HTML reports instead of text'), cfg.BoolOpt('combine', default=False, help='Generate a single report for all services'), cfg.StrOpt('output', short='o', default=None, help='Optional directory to copy generated coverage data or' ' reports into. This directory must not already exist ' 'it will be created') ] CLI = cfg.ConfigOpts() CLI.register_cli_opts(cli_opts) CLI(argv[1:]) return CLI def main(argv): CLI = parse_opts(argv) client_args = (CONF, CONF.identity.admin_username, CONF.identity.admin_password, CONF.identity.uri, CONF.identity.admin_tenant_name) coverage_client = CoverageClientJSON(*client_args) if CLI.command == 'start': if CLI.combine: coverage_client.start_coverage_combine() else: coverage_client.start_coverage() elif CLI.command == 'stop': resp, body = coverage_client.stop_coverage() if not resp['status'] == '200': print('coverage stop failed with: %s:' % (resp['status'] + ': ' + body)) exit(int(resp['status'])) path = body['path'] if CLI.output: shutil.copytree(path, CLI.output) else: print("Data files located at: %s" % path) elif CLI.command == 'report': if CLI.xml: resp, body = coverage_client.report_coverage_xml(file=CLI.filename) elif CLI.html: resp, body = coverage_client.report_coverage_html( file=CLI.filename) else: resp, body = coverage_client.report_coverage(file=CLI.filename) if not resp['status'] == '200': print('coverage report failed with: %s:' % (resp['status'] + ': ' + body)) exit(int(resp['status'])) path = body['path'] if CLI.output: if CLI.html: shutil.copytree(path, CLI.output) else: path = os.path.dirname(path) shutil.copytree(path, CLI.output) else: if not CLI.html: path = os.path.dirname(path) print('Report files located at: %s' % path) else: print('Invalid command') exit(1) if __name__ == "__main__": main(sys.argv)