|
| 1 | +""" |
| 2 | +mbed SDK |
| 3 | +Copyright (c) 2011-2013 ARM Limited |
| 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 implied. |
| 14 | +See the License for the specific language governing permissions and |
| 15 | +limitations under the License. |
| 16 | +""" |
| 17 | +import sys |
| 18 | +import argparse |
| 19 | +import xml.etree.ElementTree as ET |
| 20 | +import requests |
| 21 | +import urlparse |
| 22 | + |
| 23 | +def create_headers(args): |
| 24 | + return { 'X-Api-Key': args.api_key } |
| 25 | + |
| 26 | +def finish_command(command, response): |
| 27 | + print(command, response.status_code, response.reason) |
| 28 | + print(response.text) |
| 29 | + |
| 30 | + if response.status_code < 400: |
| 31 | + sys.exit(0) |
| 32 | + else: |
| 33 | + sys.exit(2) |
| 34 | + |
| 35 | +def create_build(args): |
| 36 | + build = {} |
| 37 | + build['buildType'] = args.build_type |
| 38 | + build['number'] = args.build_number |
| 39 | + build['source'] = args.build_source |
| 40 | + build['status'] = 'running' |
| 41 | + |
| 42 | + if build['buildType'] == 'Pull_Request': |
| 43 | + build['buildType'] = 'Pull Request' |
| 44 | + |
| 45 | + r = requests.post(urlparse.urljoin(args.url, "api/builds"), headers=create_headers(args), json=build) |
| 46 | + |
| 47 | + if r.status_code < 400: |
| 48 | + if args.property_file_format: |
| 49 | + print("MBED_BUILD_ID=" + r.text) |
| 50 | + else: |
| 51 | + print(r.text) |
| 52 | + |
| 53 | + sys.exit(0) |
| 54 | + else: |
| 55 | + sys.exit(2) |
| 56 | + |
| 57 | +def finish_build(args): |
| 58 | + data = {} |
| 59 | + data['status'] = 'completed' |
| 60 | + |
| 61 | + r = requests.put(urlparse.urljoin(args.url, "api/builds/" + args.build_id), headers=create_headers(args), json=data) |
| 62 | + finish_command('finish-build', r) |
| 63 | + |
| 64 | +def abort_build(args): |
| 65 | + data = {} |
| 66 | + data['status'] = 'aborted' |
| 67 | + |
| 68 | + r = requests.put(urlparse.urljoin(args.url, "api/builds/" + args.build_id), headers=create_headers(args), json=data) |
| 69 | + finish_command('abort-build', r) |
| 70 | + |
| 71 | +def add_test_runs(args): |
| 72 | + tree = None |
| 73 | + |
| 74 | + try: |
| 75 | + tree = ET.parse(args.test_report) |
| 76 | + except: |
| 77 | + print(sys.exc_info()[0]) |
| 78 | + print('Invalid path to test report.') |
| 79 | + sys.exit(1) |
| 80 | + |
| 81 | + test_suites = tree.getroot() |
| 82 | + |
| 83 | + ts_data = {} |
| 84 | + ts_data['testRuns'] = [] |
| 85 | + |
| 86 | + platforms_set = set() |
| 87 | + toolchains_set = set() |
| 88 | + testIds_set = set() |
| 89 | + hostOses_set = set() |
| 90 | + |
| 91 | + hostOses_set.add(args.host_os) |
| 92 | + |
| 93 | + for test_suite in test_suites: |
| 94 | + platform = "" |
| 95 | + toolchain = "" |
| 96 | + for properties in test_suite.findall('properties'): |
| 97 | + for property in properties.findall('property'): |
| 98 | + if property.attrib['name'] == 'target': |
| 99 | + platform = property.attrib['value'] |
| 100 | + platforms_set.add(platform) |
| 101 | + elif property.attrib['name'] == 'toolchain': |
| 102 | + toolchain = property.attrib['value'] |
| 103 | + toolchains_set.add(toolchain) |
| 104 | + |
| 105 | + for test_case in test_suite.findall('testcase'): |
| 106 | + testRun = {} |
| 107 | + testRun['build'] = args.build_id |
| 108 | + testRun['hostOs'] = args.host_os |
| 109 | + testRun['platform'] = platform |
| 110 | + testRun['toolchain'] = toolchain |
| 111 | + testRun['test'] = test_case.attrib['classname'].split('.')[-1] |
| 112 | + |
| 113 | + testIds_set.add(testRun['test']) |
| 114 | + |
| 115 | + system_outs = test_case.findall('system-out') |
| 116 | + |
| 117 | + if system_outs: |
| 118 | + testRun['output'] = system_outs[0].text |
| 119 | + else: |
| 120 | + testRun['output'] = "" |
| 121 | + |
| 122 | + errors = test_case.findall('error') |
| 123 | + |
| 124 | + if errors: |
| 125 | + testRun['pass'] = False |
| 126 | + testRun['result'] = errors[0].attrib['message'] |
| 127 | + else: |
| 128 | + testRun['pass'] = True |
| 129 | + testRun['result'] = 'OK' |
| 130 | + |
| 131 | + ts_data['testRuns'].append(testRun) |
| 132 | + |
| 133 | + ts_data['platforms'] = list(platforms_set) |
| 134 | + ts_data['toolchains'] = list(toolchains_set) |
| 135 | + ts_data['testIds'] = list(testIds_set) |
| 136 | + ts_data['hostOses'] = list(hostOses_set) |
| 137 | + |
| 138 | + r = requests.post(urlparse.urljoin(args.url, "api/testRuns"), headers=create_headers(args), json=ts_data) |
| 139 | + finish_command('add-test-runs', r) |
| 140 | + |
| 141 | +def main(arguments): |
| 142 | + # Register and parse command line arguments |
| 143 | + parser = argparse.ArgumentParser() |
| 144 | + parser.add_argument('-u', '--url', required=True, help='url to ci site') |
| 145 | + parser.add_argument('-k', '--api-key', required=True, help='api-key for posting data') |
| 146 | + |
| 147 | + subparsers = parser.add_subparsers(help='subcommand help') |
| 148 | + |
| 149 | + create_build_parser = subparsers.add_parser('create-build', help='create a new build') |
| 150 | + create_build_parser.add_argument('-b', '--build-number', required=True, help='build number') |
| 151 | + create_build_parser.add_argument('-T', '--build-type', choices=['Nightly', 'Limited', 'Pull_Request'], required=True, help='type of build') |
| 152 | + create_build_parser.add_argument('-s', '--build-source', required=True, help='url to source of build') |
| 153 | + create_build_parser.add_argument('-p', '--property-file-format', action='store_true', help='print result in the property file format') |
| 154 | + create_build_parser.set_defaults(func=create_build) |
| 155 | + |
| 156 | + finish_build_parser = subparsers.add_parser('finish-build', help='finish a running build') |
| 157 | + finish_build_parser.add_argument('-b', '--build-id', required=True, help='build id') |
| 158 | + finish_build_parser.set_defaults(func=finish_build) |
| 159 | + |
| 160 | + abort_build_parser = subparsers.add_parser('abort-build', help='abort a running build') |
| 161 | + abort_build_parser.add_argument('-b', '--build-id', required=True, help='build id') |
| 162 | + abort_build_parser.set_defaults(func=abort_build) |
| 163 | + |
| 164 | + add_test_runs_parser = subparsers.add_parser('add-test-runs', help='add test runs to a build') |
| 165 | + add_test_runs_parser.add_argument('-b', '--build-id', required=True, help='build id') |
| 166 | + add_test_runs_parser.add_argument('-t', '--test-report', required=True, help='path to junit xml test report') |
| 167 | + add_test_runs_parser.add_argument('-o', '--host-os', required=True, help='host os on which test was run') |
| 168 | + add_test_runs_parser.set_defaults(func=add_test_runs) |
| 169 | + |
| 170 | + args = parser.parse_args(arguments) |
| 171 | + args.func(args) |
| 172 | + |
| 173 | +if __name__ == '__main__': |
| 174 | + main(sys.argv[1:]) |
0 commit comments