Script to check a new SDK release by using the online compiler API to compile a simple program against various targets.
check_release.py@0:bdd0ba470ddc, 2014-08-15 (annotated)
- Committer:
- Bogdan Marinescu
- Date:
- Fri Aug 15 15:19:41 2014 +0100
- Revision:
- 0:bdd0ba470ddc
Initial release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Bogdan Marinescu |
0:bdd0ba470ddc | 1 | # Script to check a new SKD release |
Bogdan Marinescu |
0:bdd0ba470ddc | 2 | # Compiles a simple 'blinky' example for as many platforms as possible |
Bogdan Marinescu |
0:bdd0ba470ddc | 3 | # Reports errors or success |
Bogdan Marinescu |
0:bdd0ba470ddc | 4 | # Uses the online compiler API at https://mbed.org/handbook/Compile-API |
Bogdan Marinescu |
0:bdd0ba470ddc | 5 | # Based on the example from https://mbed.org/teams/mbed/code/mbed-API-helper/ |
Bogdan Marinescu |
0:bdd0ba470ddc | 6 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 7 | ################################################################################ |
Bogdan Marinescu |
0:bdd0ba470ddc | 8 | # Configuration section |
Bogdan Marinescu |
0:bdd0ba470ddc | 9 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 10 | # mbed_repo_path (optional): path to a github clone of the mbed repo. If found, |
Bogdan Marinescu |
0:bdd0ba470ddc | 11 | # build_release.py in that repo will be used for the list of targets to build. |
Bogdan Marinescu |
0:bdd0ba470ddc | 12 | # If not specified, target_mapping (below) will be used instead. |
Bogdan Marinescu |
0:bdd0ba470ddc | 13 | # mbed_test_project_repo: repository of the program used for testing compilation |
Bogdan Marinescu |
0:bdd0ba470ddc | 14 | # mbed_org_user: username for mbed.org |
Bogdan Marinescu |
0:bdd0ba470ddc | 15 | # mbed_org_password (optional): password for 'mbed_org_user' |
Bogdan Marinescu |
0:bdd0ba470ddc | 16 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 17 | mbed_repo_path = "c:/work/mbed/github" |
Bogdan Marinescu |
0:bdd0ba470ddc | 18 | mbed_org_user = "bogdanm" |
Bogdan Marinescu |
0:bdd0ba470ddc | 19 | mbed_test_project_repo = "https://mbed.org/users/bogdanm/code/test_new_lib_mylib" |
Bogdan Marinescu |
0:bdd0ba470ddc | 20 | ################################################################################ |
Bogdan Marinescu |
0:bdd0ba470ddc | 21 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 22 | from os.path import abspath, join, dirname |
Bogdan Marinescu |
0:bdd0ba470ddc | 23 | import os, getpass, sys, json, time, requests, logging |
Bogdan Marinescu |
0:bdd0ba470ddc | 24 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 25 | # Mapping between target name in offline build system and target name in online |
Bogdan Marinescu |
0:bdd0ba470ddc | 26 | # build system. This really shouldn't be needed. |
Bogdan Marinescu |
0:bdd0ba470ddc | 27 | target_mapping = { |
Bogdan Marinescu |
0:bdd0ba470ddc | 28 | 'LPC11U24': 'mbed-LPC11U24', |
Bogdan Marinescu |
0:bdd0ba470ddc | 29 | 'LPC1768': 'mbed-LPC1768', |
Bogdan Marinescu |
0:bdd0ba470ddc | 30 | 'UBLOX_C027': 'u-blox-C027', |
Bogdan Marinescu |
0:bdd0ba470ddc | 31 | 'ARCH_PRO': 'Seeeduino-Arch-Pro', |
Bogdan Marinescu |
0:bdd0ba470ddc | 32 | 'LPC2368': 'mbed-LPC2368', |
Bogdan Marinescu |
0:bdd0ba470ddc | 33 | 'LPC812': 'NXP-LPC800-MAX', |
Bogdan Marinescu |
0:bdd0ba470ddc | 34 | 'LPC1347': 'DipCortex-M3', |
Bogdan Marinescu |
0:bdd0ba470ddc | 35 | 'LPC4088': 'EA-LPC4088', |
Bogdan Marinescu |
0:bdd0ba470ddc | 36 | 'LPC1114': 'LPC1114FN28', |
Bogdan Marinescu |
0:bdd0ba470ddc | 37 | 'LPC11U35_401': 'EA-LPC11U35', |
Bogdan Marinescu |
0:bdd0ba470ddc | 38 | 'LPC11U35_501': 'TG-LPC11U35-501', |
Bogdan Marinescu |
0:bdd0ba470ddc | 39 | 'LPC1549': 'LPCXpresso1549', |
Bogdan Marinescu |
0:bdd0ba470ddc | 40 | 'XADOW_M0': 'Seeed-Xadow-M0', |
Bogdan Marinescu |
0:bdd0ba470ddc | 41 | 'ARCH_GPRS': 'Seeed-Arch-GPRS', |
Bogdan Marinescu |
0:bdd0ba470ddc | 42 | 'KL05Z': 'FRDM-KL05Z', |
Bogdan Marinescu |
0:bdd0ba470ddc | 43 | 'KL25Z': 'KL25Z', |
Bogdan Marinescu |
0:bdd0ba470ddc | 44 | 'KL46Z': 'FRDM-KL46Z', |
Bogdan Marinescu |
0:bdd0ba470ddc | 45 | 'K64F': 'FRDM-K64F', |
Bogdan Marinescu |
0:bdd0ba470ddc | 46 | 'K20D50M': 'FRDM-K20D50M', |
Bogdan Marinescu |
0:bdd0ba470ddc | 47 | 'NUCLEO_F030R8': 'ST-Nucleo-F030R8', |
Bogdan Marinescu |
0:bdd0ba470ddc | 48 | 'NUCLEO_F072RB': 'ST-Nucleo-F072RB', |
Bogdan Marinescu |
0:bdd0ba470ddc | 49 | 'NUCLEO_F103RB': 'ST-Nucleo-F103RB', |
Bogdan Marinescu |
0:bdd0ba470ddc | 50 | 'NUCLEO_F302R8': 'ST-Nucleo-F302R8', |
Bogdan Marinescu |
0:bdd0ba470ddc | 51 | 'NUCLEO_F334R8': 'ST-Nucleo-F334R8', |
Bogdan Marinescu |
0:bdd0ba470ddc | 52 | 'NUCLEO_F401RE': 'ST-Nucleo-F401RE', |
Bogdan Marinescu |
0:bdd0ba470ddc | 53 | 'NUCLEO_F411RE': 'ST-Nucleo-F411RE', |
Bogdan Marinescu |
0:bdd0ba470ddc | 54 | 'NUCLEO_L053R8': 'ST-Nucleo-L053R8', |
Bogdan Marinescu |
0:bdd0ba470ddc | 55 | 'NUCLEO_L152RE': 'ST-Nucleo-L152RE', |
Bogdan Marinescu |
0:bdd0ba470ddc | 56 | 'NRF51822': 'Nordic-nRF51822', |
Bogdan Marinescu |
0:bdd0ba470ddc | 57 | 'HRM1017': 'mbed-HRM1017', |
Bogdan Marinescu |
0:bdd0ba470ddc | 58 | 'ARCH_BLE': 'Seeed-Arch-BLE', |
Bogdan Marinescu |
0:bdd0ba470ddc | 59 | 'RBLAB_NRF51822': 'RedBearLab-nRF51822', |
Bogdan Marinescu |
0:bdd0ba470ddc | 60 | 'LPC11U68': 'LPCXpresso11U68', |
Bogdan Marinescu |
0:bdd0ba470ddc | 61 | 'GHI_MBUINO': 'Outrageous-Circuits-mBuino', |
Bogdan Marinescu |
0:bdd0ba470ddc | 62 | } |
Bogdan Marinescu |
0:bdd0ba470ddc | 63 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 64 | reverse_target_mapping = dict([(target_mapping[k], k) for k in target_mapping.keys()]) |
Bogdan Marinescu |
0:bdd0ba470ddc | 65 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 66 | # Get list of targets to build from build_release.py |
Bogdan Marinescu |
0:bdd0ba470ddc | 67 | # And map the target names to the ones used in the online build system |
Bogdan Marinescu |
0:bdd0ba470ddc | 68 | def get_target_list(): |
Bogdan Marinescu |
0:bdd0ba470ddc | 69 | offline_list, online_list, skipped = [e[0] for e in OFFICIAL_MBED_LIBRARY_BUILD], [], [] |
Bogdan Marinescu |
0:bdd0ba470ddc | 70 | for t in offline_list: |
Bogdan Marinescu |
0:bdd0ba470ddc | 71 | if target_mapping.has_key(t): |
Bogdan Marinescu |
0:bdd0ba470ddc | 72 | online_list.append(target_mapping[t]) |
Bogdan Marinescu |
0:bdd0ba470ddc | 73 | else: |
Bogdan Marinescu |
0:bdd0ba470ddc | 74 | skipped.append(t) |
Bogdan Marinescu |
0:bdd0ba470ddc | 75 | logging.warn("Target '%s' not found" % t) |
Bogdan Marinescu |
0:bdd0ba470ddc | 76 | return online_list, skipped |
Bogdan Marinescu |
0:bdd0ba470ddc | 77 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 78 | # Compile the test project for the given target |
Bogdan Marinescu |
0:bdd0ba470ddc | 79 | def compile_for_target(target): |
Bogdan Marinescu |
0:bdd0ba470ddc | 80 | payload = {'clean': False, 'platform': target, 'repo': mbed_test_project_repo} |
Bogdan Marinescu |
0:bdd0ba470ddc | 81 | auth = (mbed_org_user, mbed_org_password) |
Bogdan Marinescu |
0:bdd0ba470ddc | 82 | r = requests.post("https://mbed.org/api/v2/tasks/compiler/start/", data = payload, auth = auth) |
Bogdan Marinescu |
0:bdd0ba470ddc | 83 | logging.debug("%s" % r.content) |
Bogdan Marinescu |
0:bdd0ba470ddc | 84 | if r.status_code != 200: |
Bogdan Marinescu |
0:bdd0ba470ddc | 85 | if r.content == "Authorization Required": |
Bogdan Marinescu |
0:bdd0ba470ddc | 86 | return False, "invalid username/password" |
Bogdan Marinescu |
0:bdd0ba470ddc | 87 | else: |
Bogdan Marinescu |
0:bdd0ba470ddc | 88 | return False, "Error while talking to the mbed API" |
Bogdan Marinescu |
0:bdd0ba470ddc | 89 | uuid = json.loads(r.content)['result']['data']['task_id'] |
Bogdan Marinescu |
0:bdd0ba470ddc | 90 | logging.debug("Task accepted and given ID: %s" % uuid) |
Bogdan Marinescu |
0:bdd0ba470ddc | 91 | success, errors = False, [] |
Bogdan Marinescu |
0:bdd0ba470ddc | 92 | # Poll for output |
Bogdan Marinescu |
0:bdd0ba470ddc | 93 | for check in range(0, 40): |
Bogdan Marinescu |
0:bdd0ba470ddc | 94 | logging.debug("Checking for output: cycle %s" % check) |
Bogdan Marinescu |
0:bdd0ba470ddc | 95 | time.sleep(2) |
Bogdan Marinescu |
0:bdd0ba470ddc | 96 | r = requests.get("https://mbed.org/api/v2/tasks/compiler/output/%s" % uuid, auth = auth) |
Bogdan Marinescu |
0:bdd0ba470ddc | 97 | logging.debug(r.content) |
Bogdan Marinescu |
0:bdd0ba470ddc | 98 | response = json.loads(r.content) |
Bogdan Marinescu |
0:bdd0ba470ddc | 99 | messages = response['result']['data']['new_messages'] |
Bogdan Marinescu |
0:bdd0ba470ddc | 100 | for message in messages: |
Bogdan Marinescu |
0:bdd0ba470ddc | 101 | if message.get('severity', False) == 'error': |
Bogdan Marinescu |
0:bdd0ba470ddc | 102 | errors.append({"file": message["file"], "error": message["message"]}) |
Bogdan Marinescu |
0:bdd0ba470ddc | 103 | elif message.get('type', False) == 'tool_error': |
Bogdan Marinescu |
0:bdd0ba470ddc | 104 | errors.append({"file": "", "error": message["message"]}) |
Bogdan Marinescu |
0:bdd0ba470ddc | 105 | if response['result']['data']['task_complete']: |
Bogdan Marinescu |
0:bdd0ba470ddc | 106 | logging.info("Task completed.") |
Bogdan Marinescu |
0:bdd0ba470ddc | 107 | success = response['result']['data']['compilation_success'] |
Bogdan Marinescu |
0:bdd0ba470ddc | 108 | logging.info("Compile success: %s" % success) |
Bogdan Marinescu |
0:bdd0ba470ddc | 109 | break |
Bogdan Marinescu |
0:bdd0ba470ddc | 110 | else: |
Bogdan Marinescu |
0:bdd0ba470ddc | 111 | errors = "Timeout" |
Bogdan Marinescu |
0:bdd0ba470ddc | 112 | return success, errors |
Bogdan Marinescu |
0:bdd0ba470ddc | 113 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 114 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 115 | if '-d' in sys.argv: |
Bogdan Marinescu |
0:bdd0ba470ddc | 116 | logging.basicConfig(level = logging.DEBUG) |
Bogdan Marinescu |
0:bdd0ba470ddc | 117 | sys.argv.remove('-d') |
Bogdan Marinescu |
0:bdd0ba470ddc | 118 | else: |
Bogdan Marinescu |
0:bdd0ba470ddc | 119 | logging.basicConfig(level = logging.WARN) |
Bogdan Marinescu |
0:bdd0ba470ddc | 120 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 121 | # Try to get list of targets to build for from build_release.py |
Bogdan Marinescu |
0:bdd0ba470ddc | 122 | if len(sys.argv) > 1: |
Bogdan Marinescu |
0:bdd0ba470ddc | 123 | targets, skipped = sys.argv[1:], [] |
Bogdan Marinescu |
0:bdd0ba470ddc | 124 | else: |
Bogdan Marinescu |
0:bdd0ba470ddc | 125 | try: |
Bogdan Marinescu |
0:bdd0ba470ddc | 126 | import sys |
Bogdan Marinescu |
0:bdd0ba470ddc | 127 | sys.path.insert(0, mbed_repo_path) |
Bogdan Marinescu |
0:bdd0ba470ddc | 128 | from workspace_tools.build_release import OFFICIAL_MBED_LIBRARY_BUILD |
Bogdan Marinescu |
0:bdd0ba470ddc | 129 | logging.info("Got target list from build_release.py") |
Bogdan Marinescu |
0:bdd0ba470ddc | 130 | targets, skipped = get_target_list() |
Bogdan Marinescu |
0:bdd0ba470ddc | 131 | except: |
Bogdan Marinescu |
0:bdd0ba470ddc | 132 | logging.info("build_release.py not found, will try to build all known targets") |
Bogdan Marinescu |
0:bdd0ba470ddc | 133 | targets, skipped = target_mapping.values(), [] |
Bogdan Marinescu |
0:bdd0ba470ddc | 134 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 135 | # Get password once |
Bogdan Marinescu |
0:bdd0ba470ddc | 136 | try: |
Bogdan Marinescu |
0:bdd0ba470ddc | 137 | mbed_org_password |
Bogdan Marinescu |
0:bdd0ba470ddc | 138 | except: |
Bogdan Marinescu |
0:bdd0ba470ddc | 139 | mbed_org_password = getpass.getpass("Password for '%s': " % mbed_org_user) |
Bogdan Marinescu |
0:bdd0ba470ddc | 140 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 141 | if not mbed_test_project_repo.endswith('/'): |
Bogdan Marinescu |
0:bdd0ba470ddc | 142 | mbed_test_project_repo = mbed_test_project_repo + '/' |
Bogdan Marinescu |
0:bdd0ba470ddc | 143 | ok, failed = [], [] |
Bogdan Marinescu |
0:bdd0ba470ddc | 144 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 145 | for t in targets: |
Bogdan Marinescu |
0:bdd0ba470ddc | 146 | sys.stdout.write("Compiling for target '%s' (%s) ... " % (t, reverse_target_mapping[t])) |
Bogdan Marinescu |
0:bdd0ba470ddc | 147 | sys.stdout.flush() |
Bogdan Marinescu |
0:bdd0ba470ddc | 148 | res, errors = compile_for_target(t) |
Bogdan Marinescu |
0:bdd0ba470ddc | 149 | if res: |
Bogdan Marinescu |
0:bdd0ba470ddc | 150 | print "OK" |
Bogdan Marinescu |
0:bdd0ba470ddc | 151 | ok.append(t) |
Bogdan Marinescu |
0:bdd0ba470ddc | 152 | else: |
Bogdan Marinescu |
0:bdd0ba470ddc | 153 | if type(errors) == type([]) and errors: |
Bogdan Marinescu |
0:bdd0ba470ddc | 154 | print "BUILD ERROR!" |
Bogdan Marinescu |
0:bdd0ba470ddc | 155 | for e in errors: |
Bogdan Marinescu |
0:bdd0ba470ddc | 156 | print " '%s': %s" % (e["file"], e["error"]) |
Bogdan Marinescu |
0:bdd0ba470ddc | 157 | else: |
Bogdan Marinescu |
0:bdd0ba470ddc | 158 | print "ERROR: '%s'" % errors |
Bogdan Marinescu |
0:bdd0ba470ddc | 159 | failed.append(t) |
Bogdan Marinescu |
0:bdd0ba470ddc | 160 | |
Bogdan Marinescu |
0:bdd0ba470ddc | 161 | print "Compiled OK : " + (", ".join(ok) if ok else "none") |
Bogdan Marinescu |
0:bdd0ba470ddc | 162 | print "Compilation errors: " + (", ".join(failed) if failed else "none") |
Bogdan Marinescu |
0:bdd0ba470ddc | 163 | print "Skipped : " + (", ".join(skipped) if skipped else "none") |