mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #10254 from theotherjimmy/remove-some-deadcode
Remove unused tools modules and document the used ones.pull/10382/head
						commit
						dc1198b5c8
					
				| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
# Mbed OS Build Tools
 | 
			
		||||
 | 
			
		||||
This directory contains the python tools used for building Mbed OS and
 | 
			
		||||
Mbed 2. 
 | 
			
		||||
 | 
			
		||||
Quick navigation:
 | 
			
		||||
 | 
			
		||||
| file/directory        | Purpose/function                               |
 | 
			
		||||
|-----------------------|------------------------------------------------|
 | 
			
		||||
| `build.py`            | implementation of `mbed compile --library`     |
 | 
			
		||||
| `build_api.py`        | full-project build operations                  |
 | 
			
		||||
| `build_release.py`    | CLI for making an mbed 2 release               |
 | 
			
		||||
| `config`              | implementation of Config System                |
 | 
			
		||||
| `debug_tools`         | Crash log parsing                              |
 | 
			
		||||
| `default_settings.py` | Default version of project local `settings.py` |
 | 
			
		||||
| `detect_targets.py`   | implementation of `mbed detect`                |
 | 
			
		||||
| `device_management.py`| implementation of `mbed device-management`     |
 | 
			
		||||
| `export`              | Export plugins and API for woking with them    | 
 | 
			
		||||
| `flash_algo`          | CMSIS flash algorithm parser                   |
 | 
			
		||||
| `get_config.py`       | implementation of `mbed compile --config`      |
 | 
			
		||||
| `host_tests`          | location of pre-htrun host tests               |
 | 
			
		||||
| `importer`            | code importer for use with CMSIS, TFM/PSA etc. |
 | 
			
		||||
| `libraries.py`        | constants for building mbed 2 libraries        |
 | 
			
		||||
| `make.py`             | implementation of `mbed compile`               |
 | 
			
		||||
| `memap.py`            | map file parser and sumary generator           |
 | 
			
		||||
| `notifier`            | API for seting compile status to a frontend    |
 | 
			
		||||
| `options.py`          | Default option parser and option utilities     |
 | 
			
		||||
| `paths.py`            | constants for many paths used                  |
 | 
			
		||||
| `profiles`            | location of the default build profiles         |
 | 
			
		||||
| `project.py`          | implementation of `mbed export`                |
 | 
			
		||||
| `psa`                 | PSA                                            |
 | 
			
		||||
| `regions.py`          | merging from managed bootloader mode           |
 | 
			
		||||
| `resources`           | scans directories for files used in a project  |
 | 
			
		||||
| `run_icetea.py`       | implementation of `mbed test --icetea`         |
 | 
			
		||||
| `settings.py`         | project specific settings from env vars        |
 | 
			
		||||
| `singletest.py`       | location of pre-greentea greentea              |
 | 
			
		||||
| `targets`             | target description reader and post-build steps |
 | 
			
		||||
| `test`                | unit tests for tools                           |
 | 
			
		||||
| `test_api.py`         | part of pre-greentea greentea                  |
 | 
			
		||||
| `test_configs`        | configuration files used by `mbed test`        |
 | 
			
		||||
| `test_exporters.py`   | part of pre-greentea greentea                  |
 | 
			
		||||
| `tests.py`            | implementation of `mbed test --greentea`       |
 | 
			
		||||
| `toolchains`          | API for calling the selected compiler          |
 | 
			
		||||
| `utils.py`            | General purpose utilities like file moving     |
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,408 +0,0 @@
 | 
			
		|||
#!/usr/bin/env python2
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
Travis-CI build script
 | 
			
		||||
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
from __future__ import print_function, division, absolute_import
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from argparse import ArgumentParser
 | 
			
		||||
 | 
			
		||||
################################################################################
 | 
			
		||||
# Configure builds here
 | 
			
		||||
# "libs" can contain "dsp"
 | 
			
		||||
 | 
			
		||||
build_list = [
 | 
			
		||||
    {
 | 
			
		||||
    "STM":
 | 
			
		||||
        (
 | 
			
		||||
        { "target": "B96B_F446VE",       "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_L053R8",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "MTB_RAK811",        "toolchains": "GCC_ARM"},
 | 
			
		||||
        { "target": "NUCLEO_L152RE",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F030R8",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F031K6",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F042K6",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F070RB",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F072RB",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F091RC",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F103RB",     "toolchains": "GCC_ARM" },
 | 
			
		||||
        { "target": "NUCLEO_F207ZG",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F302R8",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F303K8",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F303RE",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F303ZE",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F334R8",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F401RE",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "STEVAL_3DP001V1",   "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] },
 | 
			
		||||
        { "target": "NUCLEO_F410RB",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F411RE",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F412ZG",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F413ZH",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_L432KC",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "MTB_ADV_WISE_1510", "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_L476RG",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_L011K4",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_L031K6",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_L073RZ",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F429ZI",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F446RE",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F446ZE",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F746ZG",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_F767ZI",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_L496ZG",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "NUCLEO_WB55RG",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
 | 
			
		||||
        { "target": "MOTE_L152RC",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
 | 
			
		||||
        { "target": "ELMO_F411RE",       "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
 | 
			
		||||
        { "target": "MTS_MDOT_F405RG",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "MTS_MDOT_F411RE",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "MTS_DRAGONFLY_F411RE", "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "ARCH_MAX",          "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
 | 
			
		||||
        { "target": "DISCO_F051R8",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F303VC",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F334C8",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F401VC",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
 | 
			
		||||
        { "target": "DISCO_F407VG",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F413ZH",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F429ZI",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F469NI",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F746NG",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_F769NI",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_L475VG_IOT01A", "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_L476VG",        "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        { "target": "DISCO_L072CZ_LRWAN1", "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
 | 
			
		||||
        # module manufacturer : muRata
 | 
			
		||||
        { "target": "MTB_MURATA_ABZ",    "toolchains": "GCC_ARM", "libs": [] },
 | 
			
		||||
        ),
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "NXP":
 | 
			
		||||
        (
 | 
			
		||||
            { "target": "LPC1768",           "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "LPC11U24",          "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "OC_MBUINO",         "toolchains": "GCC_ARM", "libs": []  },
 | 
			
		||||
 | 
			
		||||
            { "target": "LPC11U24_301",      "toolchains": "GCC_ARM", "libs": [] },
 | 
			
		||||
            { "target": "LPC1114",           "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "LPC11U35_401",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "UBLOX_C027",        "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "LPC11U35_501",      "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "LPC11U68",          "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "LPC11U37H_401",     "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "LPC1549",           "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "KL05Z",             "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "KL25Z",             "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "KL27Z",             "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "KL43Z",             "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "KL46Z",             "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "K20D50M",           "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "TEENSY3_1",         "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "K64F",              "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "K22F",              "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "LPC4088",           "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "ARCH_PRO",          "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        )
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "NORDIC":
 | 
			
		||||
        (
 | 
			
		||||
            { "target": "NRF51822",          "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "DELTA_DFCM_NNN40",  "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "NRF51_DK",          "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "NRF51_MICROBIT",    "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        )
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "SILICON_LABS":
 | 
			
		||||
        (
 | 
			
		||||
            { "target": "EFM32ZG_STK3200",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "EFM32HG_STK3400",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "EFM32LG_STK3600",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "EFM32GG_STK3700",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "EFM32WG_STK3800",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "EFM32PG_STK3401",   "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        )
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "ATMEL":
 | 
			
		||||
        (
 | 
			
		||||
            { "target": "SAMR21G18A",  "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "SAMD21J18A",  "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "SAMD21G18A",  "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
            { "target": "SAML21J18A",  "toolchains": "GCC_ARM", "libs": ["dsp"] },
 | 
			
		||||
        )
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "NUVOTON":
 | 
			
		||||
        (
 | 
			
		||||
            { "target": "NUMAKER_PFM_NUC472",   "toolchains": "GCC_ARM",    "libs": ["dsp"] },
 | 
			
		||||
            { "target": "NUMAKER_PFM_M453",     "toolchains": "GCC_ARM",    "libs": ["dsp"] },
 | 
			
		||||
            { "target": "NUMAKER_PFM_M487",     "toolchains": "GCC_ARM",    "libs": ["dsp"] },
 | 
			
		||||
        )
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "RENESAS":
 | 
			
		||||
        (
 | 
			
		||||
            { "target": "RZ_A1H",    "toolchains": "GCC_ARM" },
 | 
			
		||||
            { "target": "GR_LYCHEE", "toolchains": "GCC_ARM" },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
################################################################################
 | 
			
		||||
# Configure example test building (linking against external mbed SDK libraries)
 | 
			
		||||
 | 
			
		||||
linking_list = [
 | 
			
		||||
    {
 | 
			
		||||
    "NXP": (
 | 
			
		||||
            {"target": "LPC1768",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_15", "MBED_16", "MBED_17"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "K64F",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "K22F",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "KL43Z",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
         )
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        "STM": (
 | 
			
		||||
            {"target": "NUCLEO_F446RE",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_F446ZE",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_F401RE",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                     }
 | 
			
		||||
            },
 | 
			
		||||
            {"target": "NUCLEO_F411RE",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_F412ZG",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                     }
 | 
			
		||||
            },
 | 
			
		||||
            {"target": "NUCLEO_F413ZH",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                     }
 | 
			
		||||
            },
 | 
			
		||||
            {"target": "NUCLEO_F429ZI",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_F207ZG",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_F746ZG",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_F767ZI",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_L476RG",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                     }
 | 
			
		||||
            },
 | 
			
		||||
            {"target": "DISCO_F429ZI",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                     }
 | 
			
		||||
            },
 | 
			
		||||
            {"target": "DISCO_F407VG",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
             {"target": "DISCO_F413ZH",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUCLEO_F303ZE",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                     }
 | 
			
		||||
            },
 | 
			
		||||
            {"target": "DISCO_L475VG_IOT01A",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "DISCO_L476VG",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "DISCO_L072CZ_LRWAN1",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                      }
 | 
			
		||||
            },
 | 
			
		||||
            {"target": "MTB_MURATA_ABZ",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                      }
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "NUVOTON": (
 | 
			
		||||
            {"target": "NUMAKER_PFM_NUC472",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUMAKER_PFM_M453",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             },
 | 
			
		||||
            {"target": "NUMAKER_PFM_M487",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                       }
 | 
			
		||||
             }
 | 
			
		||||
        )
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "RENESAS":
 | 
			
		||||
        (
 | 
			
		||||
            {
 | 
			
		||||
             "target": "RZ_A1H",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                      }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
             "target": "GR_LYCHEE",
 | 
			
		||||
             "toolchains": "GCC_ARM",
 | 
			
		||||
             "tests": {""     : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"],
 | 
			
		||||
                      }
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
################################################################################
 | 
			
		||||
 | 
			
		||||
# Driver
 | 
			
		||||
 | 
			
		||||
def run_builds(dry_run, vendor):
 | 
			
		||||
    for vendor_list in build_list:
 | 
			
		||||
        if vendor in vendor_list:
 | 
			
		||||
            for build in vendor_list[vendor]:
 | 
			
		||||
                toolchain_list = build["toolchains"]
 | 
			
		||||
                if type(toolchain_list) != type([]): toolchain_list = [toolchain_list]
 | 
			
		||||
                for toolchain in toolchain_list:
 | 
			
		||||
                    cmdline = ("%s tools/build.py -m %s -t %s -c --silent "%
 | 
			
		||||
                               (sys.executable, build["target"], toolchain))
 | 
			
		||||
                    libs = build.get("libs", [])
 | 
			
		||||
                    if libs:
 | 
			
		||||
                        cmdline = cmdline + " ".join(["--" + l for l in libs])
 | 
			
		||||
                    print("Executing: %s" % cmdline)
 | 
			
		||||
                    if not dry_run:
 | 
			
		||||
                        if os.system(cmdline) != 0:
 | 
			
		||||
                            sys.exit(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run_test_linking(dry_run, vendor):
 | 
			
		||||
    """ Function run make.py commands to build and link simple mbed SDK
 | 
			
		||||
        tests against few libraries to make sure there are no simple linking errors.
 | 
			
		||||
    """
 | 
			
		||||
    for vendor_list in linking_list:
 | 
			
		||||
        if vendor in vendor_list:
 | 
			
		||||
            for link in vendor_list[vendor]:
 | 
			
		||||
                toolchain_list = link["toolchains"]
 | 
			
		||||
                if type(toolchain_list) != type([]):
 | 
			
		||||
                    toolchain_list = [toolchain_list]
 | 
			
		||||
                for toolchain in toolchain_list:
 | 
			
		||||
                    tests = link["tests"]
 | 
			
		||||
                    # Call make.py for each test group for particular library
 | 
			
		||||
                    for test_lib in tests:
 | 
			
		||||
                        test_names = tests[test_lib]
 | 
			
		||||
                        test_lib_switch = "--" + test_lib if test_lib else ""
 | 
			
		||||
                        cmdline = ("%s tools/make.py -m %s -t %s -c --silent %s "
 | 
			
		||||
                                   "-n %s" % (sys.executable, link["target"],
 | 
			
		||||
                                               toolchain, test_lib_switch,
 | 
			
		||||
                                               ",".join(test_names)))
 | 
			
		||||
                        print("Executing: %s" % cmdline)
 | 
			
		||||
                        if not dry_run:
 | 
			
		||||
                            if os.system(cmdline) != 0:
 | 
			
		||||
                                sys.exit(1)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    parser = ArgumentParser()
 | 
			
		||||
 | 
			
		||||
    parser.add_argument("--vendor",
 | 
			
		||||
                        metavar="vendor",
 | 
			
		||||
                        type=str.upper,
 | 
			
		||||
                        help="Select a vendor to run travis tests"
 | 
			
		||||
                        )
 | 
			
		||||
 | 
			
		||||
    options = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    run_builds("-s" in sys.argv, options.vendor)
 | 
			
		||||
    run_test_linking("-s" in sys.argv, options.vendor)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
{
 | 
			
		||||
  "config" : {
 | 
			
		||||
    "mbed_repo_path" : "C:/Users/annbri01/Work/Mercurial"
 | 
			
		||||
  },
 | 
			
		||||
  "test_list" : [
 | 
			
		||||
    { 
 | 
			
		||||
      "name" : "test_compile_mbed_lib",
 | 
			
		||||
      "lib" : "mbed"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name" : "test_compile_mbed_dev",
 | 
			
		||||
      "lib" : "mbed-dev"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "target_list" : [],
 | 
			
		||||
  "ignore_list" : []
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,548 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright (c) 2016-2019 ARM Limited. All rights reserved.
 | 
			
		||||
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
# Script to check a new mbed 2 release by compiling a set of specified test apps 
 | 
			
		||||
# for all currently supported platforms. Each test app must include an mbed library.
 | 
			
		||||
# This can either be the pre-compiled version 'mbed' or the source version 'mbed-dev'.
 | 
			
		||||
#
 | 
			
		||||
# Setup:
 | 
			
		||||
# 1. Set up your global .hgrc file
 | 
			
		||||
# 
 | 
			
		||||
#    If you don't already have a .hgrc file in your $HOME directory, create one there.
 | 
			
		||||
#    Then add the following section:
 | 
			
		||||
# 
 | 
			
		||||
#    [auth]
 | 
			
		||||
#    x.prefix = *
 | 
			
		||||
#    x.username = <put your mbed org username here>
 | 
			
		||||
#    x.password = <put your mbed org password here>
 | 
			
		||||
#
 | 
			
		||||
#    This has 2 purposes, the first means you don't get prompted for your password 
 | 
			
		||||
#    whenever you run hg commands on the commandline. The second is that this script
 | 
			
		||||
#    reads these details in order to fully automate the Mercurial commands.
 | 
			
		||||
# 
 | 
			
		||||
# Edit "check_release.json". This has the following structure:
 | 
			
		||||
#{
 | 
			
		||||
#  "config" : {
 | 
			
		||||
#    "mbed_repo_path" : "C:/Users/annbri01/Work/Mercurial"
 | 
			
		||||
#  },
 | 
			
		||||
#  "test_list" : [
 | 
			
		||||
#    {
 | 
			
		||||
#        "name" : "test_compile_mbed_lib",
 | 
			
		||||
#        "lib" : "mbed"
 | 
			
		||||
#    },
 | 
			
		||||
#    {
 | 
			
		||||
#        "name" : "test_compile_mbed_dev",
 | 
			
		||||
#        "lib" : "mbed-dev"
 | 
			
		||||
#    }
 | 
			
		||||
#  ],
 | 
			
		||||
#  "target_list" : []
 | 
			
		||||
#}
 | 
			
		||||
#
 | 
			
		||||
# The mbed_repo_path field should be changed to point to where your local
 | 
			
		||||
# working directory is for Mercurial repositories.
 | 
			
		||||
# For each test app you wish to run, add an entry to the test list. The example
 | 
			
		||||
# above has 2 test apps  
 | 
			
		||||
#     "test_compile_mbed_lib" and "test_compile_mbed_dev"
 | 
			
		||||
# The lib field in each says which type of mbed 2 library the app contains.
 | 
			
		||||
# These test apps MUST be available as repos in the user's online Mercurial area.
 | 
			
		||||
# The target_list allows the user to override the set of targets/platforms used 
 | 
			
		||||
# for the compilation.
 | 
			
		||||
# E.g to just compile for 2 targets, K64F and K22F :
 | 
			
		||||
# "target_list" : ["K64F", "K22F"]
 | 
			
		||||
#
 | 
			
		||||
# Run the script from the mbed-os directory as follows:
 | 
			
		||||
# > python tools/check_release.py 
 | 
			
		||||
#
 | 
			
		||||
# It will look for local clones of the test app repos. If they don't exist
 | 
			
		||||
# it will clone them. It will then read the latest versions of mbed and mbed-dev
 | 
			
		||||
# (an assumption is made that both of these are already cloned in your Mercurial area).
 | 
			
		||||
# The lib files within the test apps are then updated to the corresponding version in 
 | 
			
		||||
# the associated lib itself. The test apps are then committed and pushed back to the users
 | 
			
		||||
# fork.
 | 
			
		||||
# The test apps will then be compiled for all supported targets and a % result output at 
 | 
			
		||||
# the end.
 | 
			
		||||
#
 | 
			
		||||
# Uses the online compiler API at https://mbed.org/handbook/Compile-API
 | 
			
		||||
# Based on the example from https://mbed.org/teams/mbed/code/mbed-API-helper/
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
import os, getpass, sys, json, time, requests, logging
 | 
			
		||||
from os.path import dirname, abspath, basename, join
 | 
			
		||||
import argparse
 | 
			
		||||
import subprocess
 | 
			
		||||
import re
 | 
			
		||||
import hglib
 | 
			
		||||
import argparse
 | 
			
		||||
 | 
			
		||||
# Be sure that the tools directory is in the search path
 | 
			
		||||
ROOT = abspath(join(dirname(__file__), ".."))
 | 
			
		||||
sys.path.insert(0, ROOT)
 | 
			
		||||
 | 
			
		||||
from tools.build_api import get_mbed_official_release
 | 
			
		||||
 | 
			
		||||
OFFICIAL_MBED_LIBRARY_BUILD = get_mbed_official_release('2')
 | 
			
		||||
 | 
			
		||||
def get_compilation_failure(messages):
 | 
			
		||||
    """ Reads the json formatted 'messages' and checks for compilation errors.
 | 
			
		||||
        If there is a genuine compilation error then there should be a new 
 | 
			
		||||
        message containing a severity field = Error and an accompanying message 
 | 
			
		||||
        with the compile error text. Any other combination is considered an 
 | 
			
		||||
        internal compile engine failure 
 | 
			
		||||
    Args:
 | 
			
		||||
    messages - json formatted text returned by the online compiler API.
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    Either "Error" or "Internal" to indicate an actual compilation error or an 
 | 
			
		||||
    internal IDE API fault.
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    for m in messages:
 | 
			
		||||
        # Get message text if it exists
 | 
			
		||||
        try:
 | 
			
		||||
            message = m['message']
 | 
			
		||||
            message = message + "\n"
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            # Skip this message as it has no 'message' field
 | 
			
		||||
            continue
 | 
			
		||||
                 
 | 
			
		||||
        # Get type of message text
 | 
			
		||||
        try:
 | 
			
		||||
            msg_type = m['type']
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            # Skip this message as it has no 'type' field
 | 
			
		||||
            continue
 | 
			
		||||
        
 | 
			
		||||
        if msg_type == 'error' or msg_type == 'tool_error':
 | 
			
		||||
            rel_log.error(message)
 | 
			
		||||
            return "Error"
 | 
			
		||||
        else: 
 | 
			
		||||
            rel_log.debug(message)
 | 
			
		||||
 | 
			
		||||
    return "Internal"
 | 
			
		||||
                 
 | 
			
		||||
def invoke_api(payload, url, auth, polls, begin="start/"):
 | 
			
		||||
    """ Sends an API command request to the online IDE. Waits for a task completed 
 | 
			
		||||
        response before returning the results.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
    payload - Configuration parameters to be passed to the API
 | 
			
		||||
    url - THe URL for the online compiler API
 | 
			
		||||
    auth - Tuple containing authentication credentials
 | 
			
		||||
    polls - Number of times to poll for results
 | 
			
		||||
    begin - Default value = "start/", start command to be appended to URL
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    result - True/False indicating the success/failure of the compilation
 | 
			
		||||
    fail_type - the failure text if the compilation failed, else None
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    # send task to api
 | 
			
		||||
    rel_log.debug(url + begin + "| data: " + str(payload))
 | 
			
		||||
    r = requests.post(url + begin, data=payload, auth=auth)
 | 
			
		||||
    rel_log.debug(r.request.body)
 | 
			
		||||
    
 | 
			
		||||
    if r.status_code != 200:
 | 
			
		||||
        rel_log.error("HTTP code %d reported.", r.status_code)
 | 
			
		||||
        return False, "Internal"
 | 
			
		||||
 | 
			
		||||
    response = r.json()
 | 
			
		||||
    rel_log.debug(response)
 | 
			
		||||
    uuid = response['result']['data']['task_id']
 | 
			
		||||
    rel_log.debug("Task accepted and given ID: %s", uuid)
 | 
			
		||||
    result = False
 | 
			
		||||
    fail_type = None
 | 
			
		||||
    
 | 
			
		||||
    # It currently seems to take the onlide IDE API ~30s to process the compile
 | 
			
		||||
    # request and provide a response. Set the poll time to half that in case it 
 | 
			
		||||
    # does manage to compile quicker.
 | 
			
		||||
    poll_delay = 15
 | 
			
		||||
    rel_log.debug("Running with a poll for response delay of: %ss", poll_delay)
 | 
			
		||||
 | 
			
		||||
    # poll for output
 | 
			
		||||
    for check in range(polls):
 | 
			
		||||
        time.sleep(poll_delay)
 | 
			
		||||
        
 | 
			
		||||
        try:
 | 
			
		||||
            r = requests.get(url + "output/%s" % uuid, auth=auth)
 | 
			
		||||
            
 | 
			
		||||
        except ConnectionError:
 | 
			
		||||
            return "Internal"
 | 
			
		||||
 | 
			
		||||
        response = r.json()
 | 
			
		||||
 | 
			
		||||
        data = response['result']['data']
 | 
			
		||||
        if data['task_complete']:
 | 
			
		||||
            # Task completed. Now determine the result. Should be one of :
 | 
			
		||||
            # 1) Successful compilation
 | 
			
		||||
            # 2) Failed compilation with an error message
 | 
			
		||||
            # 3) Internal failure of the online compiler            
 | 
			
		||||
            result = bool(data['compilation_success'])
 | 
			
		||||
            if result:
 | 
			
		||||
                rel_log.info("COMPILATION SUCCESSFUL\n")
 | 
			
		||||
            else:
 | 
			
		||||
                # Did this fail due to a genuine compilation error or a failue of 
 | 
			
		||||
                # the api itself ?
 | 
			
		||||
                rel_log.info("COMPILATION FAILURE\n")
 | 
			
		||||
                fail_type = get_compilation_failure(data['new_messages'])
 | 
			
		||||
            break
 | 
			
		||||
    else:
 | 
			
		||||
        rel_log.info("COMPILATION FAILURE\n")
 | 
			
		||||
        
 | 
			
		||||
    if not result and fail_type == None:
 | 
			
		||||
        fail_type = "Internal"
 | 
			
		||||
        
 | 
			
		||||
    return result, fail_type
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_repo(target, program, user, pw, polls=25, 
 | 
			
		||||
               url="https://developer.mbed.org/api/v2/tasks/compiler/"):
 | 
			
		||||
    """ Wrapper for sending an API command request to the online IDE. Sends a 
 | 
			
		||||
        build request.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
    target - Target to be built
 | 
			
		||||
    program - Test program to build
 | 
			
		||||
    user - mbed username
 | 
			
		||||
    pw - mbed password
 | 
			
		||||
    polls - Number of times to poll for results
 | 
			
		||||
    url - THe URL for the online compiler API
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    result - True/False indicating the success/failure of the compilation
 | 
			
		||||
    fail_type - the failure text if the compilation failed, else None
 | 
			
		||||
    """
 | 
			
		||||
    payload = {'clean':True, 'target':target, 'program':program}
 | 
			
		||||
    auth = (user, pw)
 | 
			
		||||
    return invoke_api(payload, url, auth, polls)
 | 
			
		||||
 | 
			
		||||
def run_cmd(command, exit_on_failure=False):
 | 
			
		||||
    """ Passes a command to the system and returns a True/False result once the 
 | 
			
		||||
        command has been executed, indicating success/failure. Commands are passed
 | 
			
		||||
        as a list of tokens. 
 | 
			
		||||
        E.g. The command 'git remote -v' would be passed in as ['git', 'remote', '-v']
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
    command - system command as a list of tokens
 | 
			
		||||
    exit_on_failure - If True exit the program on failure (default = False)
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    result - True/False indicating the success/failure of the command
 | 
			
		||||
    """
 | 
			
		||||
    rel_log.debug('[Exec] %s', ' '.join(command))
 | 
			
		||||
    return_code = subprocess.call(command, shell=True)
 | 
			
		||||
    
 | 
			
		||||
    if return_code:
 | 
			
		||||
        rel_log.warning("The command '%s' failed with return code: %s",  
 | 
			
		||||
                        (' '.join(command), return_code))
 | 
			
		||||
        if exit_on_failure:
 | 
			
		||||
            sys.exit(1)
 | 
			
		||||
    
 | 
			
		||||
    return return_code
 | 
			
		||||
 | 
			
		||||
def run_cmd_with_output(command, exit_on_failure=False):
 | 
			
		||||
    """ Passes a command to the system and returns a True/False result once the 
 | 
			
		||||
        command has been executed, indicating success/failure. If the command was 
 | 
			
		||||
        successful then the output from the command is returned to the caller.
 | 
			
		||||
        Commands are passed as a list of tokens. 
 | 
			
		||||
        E.g. The command 'git remote -v' would be passed in as ['git', 'remote', '-v']
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
    command - system command as a list of tokens
 | 
			
		||||
    exit_on_failure - If True exit the program on failure (default = False)
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    result - True/False indicating the success/failure of the command
 | 
			
		||||
    output - The output of the command if it was successful, else empty string
 | 
			
		||||
    """
 | 
			
		||||
    rel_log.debug('[Exec] %s', ' '.join(command))
 | 
			
		||||
    returncode = 0
 | 
			
		||||
    output = ""
 | 
			
		||||
    try:
 | 
			
		||||
        output = subprocess.check_output(command, shell=True)
 | 
			
		||||
    except subprocess.CalledProcessError as e:
 | 
			
		||||
        rel_log.warning("The command '%s' failed with return code: %s", 
 | 
			
		||||
                        (' '.join(command), e.returncode))
 | 
			
		||||
        returncode = e.returncode
 | 
			
		||||
        if exit_on_failure:
 | 
			
		||||
            sys.exit(1)
 | 
			
		||||
    return returncode, output
 | 
			
		||||
 | 
			
		||||
def upgrade_test_repo(test, user, library, ref, repo_path):
 | 
			
		||||
    """ Upgrades a local version of a test repo to the latest version of its 
 | 
			
		||||
        embedded library.
 | 
			
		||||
        If the test repo is not present in the user area specified in the json 
 | 
			
		||||
        config file, then it will first be cloned. 
 | 
			
		||||
    Args:
 | 
			
		||||
    test - Mercurial test repo name
 | 
			
		||||
    user - Mercurial user name
 | 
			
		||||
    library - library name
 | 
			
		||||
    ref - SHA corresponding to the latest version of the library
 | 
			
		||||
    repo_path - path to the user's repo area
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    updated - True if library was updated, False otherwise
 | 
			
		||||
    """
 | 
			
		||||
    rel_log.info("Updating test repo: '%s' to SHA: %s", test, ref)
 | 
			
		||||
    cwd = os.getcwd()
 | 
			
		||||
 | 
			
		||||
    repo = "https://" + user + '@developer.mbed.org/users/' + user + '/code/' + test 
 | 
			
		||||
 | 
			
		||||
    # Clone the repo if it doesn't already exist
 | 
			
		||||
    path = abspath(repo_path + '/' + test)
 | 
			
		||||
    if not os.path.exists(path):
 | 
			
		||||
        rel_log.info("Test repo doesn't exist, cloning...")
 | 
			
		||||
        os.chdir(abspath(repo_path))        
 | 
			
		||||
        clone_cmd = ['hg', 'clone', repo]
 | 
			
		||||
        run_cmd(clone_cmd, exit_on_failure=True)
 | 
			
		||||
    
 | 
			
		||||
    os.chdir(path)
 | 
			
		||||
 | 
			
		||||
    client = hglib.open(path)        
 | 
			
		||||
 | 
			
		||||
    lib_file = library + '.lib'    
 | 
			
		||||
    if os.path.isfile(lib_file):
 | 
			
		||||
        # Rename command will fail on some OS's if the target file already exist,
 | 
			
		||||
        # so ensure if it does, it is deleted first.
 | 
			
		||||
        bak_file = library + '_bak' 
 | 
			
		||||
        if os.path.isfile(bak_file):
 | 
			
		||||
            os.remove(bak_file)
 | 
			
		||||
        
 | 
			
		||||
        os.rename(lib_file, bak_file)
 | 
			
		||||
    else:
 | 
			
		||||
        rel_log.error("Failure to backup lib file prior to updating.")
 | 
			
		||||
        return False
 | 
			
		||||
    
 | 
			
		||||
    # mbed 2 style lib file contains one line with the following format
 | 
			
		||||
    # e.g. https://developer.mbed.org/users/<user>/code/mbed-dev/#156823d33999
 | 
			
		||||
    exp = 'https://developer.mbed.org/users/' + user + '/code/' + library + '/#[A-Za-z0-9]+'
 | 
			
		||||
    lib_re = re.compile(exp)
 | 
			
		||||
    updated = False
 | 
			
		||||
 | 
			
		||||
    # Scan through mbed-os.lib line by line, looking for lib version and update 
 | 
			
		||||
    # it if found
 | 
			
		||||
    with open(bak_file, 'r') as ip, open(lib_file, 'w') as op:
 | 
			
		||||
        for line in ip:
 | 
			
		||||
 | 
			
		||||
            opline = line
 | 
			
		||||
            
 | 
			
		||||
            regexp = lib_re.match(line)
 | 
			
		||||
            if regexp:
 | 
			
		||||
                opline = 'https://developer.mbed.org/users/' + user + '/code/' + library + '/#' + ref
 | 
			
		||||
                updated = True
 | 
			
		||||
    
 | 
			
		||||
            op.write(opline)
 | 
			
		||||
 | 
			
		||||
    if updated:
 | 
			
		||||
 | 
			
		||||
        # Setup the default commit message
 | 
			
		||||
        commit_message = '"Updating ' + library + ' to ' + ref + '"' 
 | 
			
		||||
 
 | 
			
		||||
        # Setup and run the commit command. Need to use the rawcommand in the hglib
 | 
			
		||||
        # for this in order to pass the string value to the -m option. run_cmd using 
 | 
			
		||||
        # subprocess does not like this syntax.
 | 
			
		||||
        try:
 | 
			
		||||
            client.rawcommand(['commit','-m '+commit_message, lib_file])
 | 
			
		||||
 | 
			
		||||
            cmd = ['hg', 'push', '-f', repo]
 | 
			
		||||
            run_cmd(cmd, exit_on_failure=True)
 | 
			
		||||
            
 | 
			
		||||
        except:
 | 
			
		||||
            rel_log.info("Lib file already up to date and thus nothing to commit")
 | 
			
		||||
                            
 | 
			
		||||
    os.chdir(cwd)
 | 
			
		||||
    return updated
 | 
			
		||||
 | 
			
		||||
def get_sha(repo_path, library):
 | 
			
		||||
    """ Gets the latest SHA for the library specified. The library is assumed to be
 | 
			
		||||
        located at the repo_path. If a SHA cannot be obtained this script will exit.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
    library - library name
 | 
			
		||||
    repo_path - path to the user's repo area
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    sha - last commit SHA
 | 
			
		||||
    """
 | 
			
		||||
    cwd = os.getcwd()
 | 
			
		||||
    sha = None
 | 
			
		||||
    os.chdir(abspath(repo_path + '/' + library))
 | 
			
		||||
    
 | 
			
		||||
    cmd = ['hg', 'log', '-l', '1']
 | 
			
		||||
    ret, output = run_cmd_with_output(cmd, exit_on_failure=True)
 | 
			
		||||
    
 | 
			
		||||
    # Output should contain a 4 line string of the form:
 | 
			
		||||
    # changeset:   135:176b8275d35d
 | 
			
		||||
    # tag:         tip
 | 
			
		||||
    # user:        <>
 | 
			
		||||
    # date:        Thu Feb 02 16:02:30 2017 +0000
 | 
			
		||||
    # summary:     Release 135 of the mbed library
 | 
			
		||||
    # All we want is the changeset string after version number
 | 
			
		||||
    
 | 
			
		||||
    lines = output.split('\n')
 | 
			
		||||
    fields = lines[0].split(':')
 | 
			
		||||
    sha = fields[2]
 | 
			
		||||
    
 | 
			
		||||
    os.chdir(cwd)
 | 
			
		||||
    return sha
 | 
			
		||||
 | 
			
		||||
def get_latest_library_versions(repo_path):
 | 
			
		||||
    """ Returns the latest library versions (SHAs) for 'mbed' and 'mbed-dev'. 
 | 
			
		||||
    If the SHAs cannot be obtained this script will exit.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
    repo_path - path to the user's repo area
 | 
			
		||||
    
 | 
			
		||||
    Returns:
 | 
			
		||||
    mbed - last commit SHA for mbed library
 | 
			
		||||
    mbed_dev - last commit SHA for mbed_dev library
 | 
			
		||||
    
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    mbed = get_sha(repo_path, 'mbed')
 | 
			
		||||
    mbed_dev = get_sha(repo_path, 'mbed-dev')
 | 
			
		||||
 | 
			
		||||
    return mbed, mbed_dev
 | 
			
		||||
 | 
			
		||||
def log_results(lst, title):
 | 
			
		||||
    if len(lst) == 0:
 | 
			
		||||
        rel_log.info("%s - None", title)
 | 
			
		||||
    else:        
 | 
			
		||||
        for entry in lst:
 | 
			
		||||
            rel_log.info("%s - Test: %s, Target: %s", title, entry[0], entry[1])                
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
 | 
			
		||||
    parser = argparse.ArgumentParser(description=__doc__,
 | 
			
		||||
                                     formatter_class=argparse.RawDescriptionHelpFormatter)
 | 
			
		||||
    parser.add_argument('-l', '--log-level', 
 | 
			
		||||
                        help="Level for providing logging output", 
 | 
			
		||||
                        default='INFO')
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    default = getattr(logging, 'INFO')
 | 
			
		||||
    level = getattr(logging, args.log_level.upper(), default)
 | 
			
		||||
        
 | 
			
		||||
    # Set logging level
 | 
			
		||||
    logging.basicConfig(level=level)
 | 
			
		||||
    rel_log = logging.getLogger("check-release")
 | 
			
		||||
    
 | 
			
		||||
    # Read configuration data
 | 
			
		||||
    with open(os.path.join(os.path.dirname(__file__), "check_release.json")) as config:
 | 
			
		||||
        json_data = json.load(config)
 | 
			
		||||
     
 | 
			
		||||
    supported_targets = []
 | 
			
		||||
 | 
			
		||||
    if len(json_data["target_list"]) > 0:
 | 
			
		||||
        # Compile user supplied subset of targets
 | 
			
		||||
        supported_targets = json_data["target_list"]
 | 
			
		||||
    else:        
 | 
			
		||||
        # Get a list of the officially supported mbed-os 2 targets
 | 
			
		||||
        for tgt in OFFICIAL_MBED_LIBRARY_BUILD:
 | 
			
		||||
            supported_targets.append(tgt[0])
 | 
			
		||||
 | 
			
		||||
    ignore_list = []
 | 
			
		||||
 | 
			
		||||
    if len(json_data["ignore_list"]) > 0:
 | 
			
		||||
        # List of tuples of (test, target) to be ignored in this test
 | 
			
		||||
        ignore_list = json_data["ignore_list"]
 | 
			
		||||
 | 
			
		||||
    config = json_data["config"]
 | 
			
		||||
    test_list = json_data["test_list"]
 | 
			
		||||
    repo_path = config["mbed_repo_path"]
 | 
			
		||||
    tests = []
 | 
			
		||||
 | 
			
		||||
    # get username
 | 
			
		||||
    cmd = ['hg', 'config', 'auth.x.username']
 | 
			
		||||
    ret, output = run_cmd_with_output(cmd, exit_on_failure=True)
 | 
			
		||||
    output = output.split('\n')
 | 
			
		||||
    user = output[0]
 | 
			
		||||
    
 | 
			
		||||
    # get password
 | 
			
		||||
    cmd = ['hg', 'config', 'auth.x.password']
 | 
			
		||||
    ret, output = run_cmd_with_output(cmd, exit_on_failure=True)
 | 
			
		||||
    output = output.split('\n')
 | 
			
		||||
    password = output[0]
 | 
			
		||||
    
 | 
			
		||||
    mbed, mbed_dev = get_latest_library_versions(repo_path)
 | 
			
		||||
 | 
			
		||||
    if not mbed or not mbed_dev:
 | 
			
		||||
        rel_log.error("Could not obtain latest versions of library files!!")
 | 
			
		||||
        exit(1)
 | 
			
		||||
        
 | 
			
		||||
    rel_log.info("Latest mbed lib version = %s", mbed)
 | 
			
		||||
    rel_log.info("Latest mbed-dev lib version = %s", mbed_dev)    
 | 
			
		||||
  
 | 
			
		||||
    # First update test repos to latest versions of their embedded libraries
 | 
			
		||||
    for test in test_list:
 | 
			
		||||
        tests.append(test['name'])
 | 
			
		||||
        upgrade_test_repo(test['name'], user, test['lib'], 
 | 
			
		||||
                          mbed if test['lib'] == "mbed" else mbed_dev, 
 | 
			
		||||
                          repo_path)
 | 
			
		||||
 | 
			
		||||
    total = len(supported_targets) * len(tests)
 | 
			
		||||
    current = 0
 | 
			
		||||
    retries = 10
 | 
			
		||||
    passes = 0
 | 
			
		||||
    failures = []
 | 
			
		||||
    skipped = []
 | 
			
		||||
    
 | 
			
		||||
    # Compile each test for each supported target
 | 
			
		||||
    for test in tests:
 | 
			
		||||
        for target in supported_targets:
 | 
			
		||||
            
 | 
			
		||||
            combo = [test, target]
 | 
			
		||||
            
 | 
			
		||||
            if combo in ignore_list:
 | 
			
		||||
                rel_log.info("SKIPPING TEST: %s, TARGET: %s", test, target)
 | 
			
		||||
                total -= 1   
 | 
			
		||||
                skipped.append(combo)
 | 
			
		||||
                continue
 | 
			
		||||
                
 | 
			
		||||
            current += 1
 | 
			
		||||
            for retry in range(0, retries):
 | 
			
		||||
                rel_log.info("COMPILING (%d/%d): TEST %s, TARGET: %s , attempt %u\n", current, total, test, target,  retry)
 | 
			
		||||
                result, mesg = build_repo(target, test, user, password)
 | 
			
		||||
                if not result:
 | 
			
		||||
                    if mesg == 'Internal':
 | 
			
		||||
                        # Internal compiler error thus retry
 | 
			
		||||
                        continue
 | 
			
		||||
                    else:
 | 
			
		||||
                        # Actual error thus move on to next compilation
 | 
			
		||||
                        failures.append(combo)
 | 
			
		||||
                        break
 | 
			
		||||
                                    
 | 
			
		||||
                passes += (int)(result)
 | 
			
		||||
                break
 | 
			
		||||
            else:
 | 
			
		||||
                rel_log.error("Compilation failed due to internal errors.")
 | 
			
		||||
                rel_log.error("Skipping test/target combination.")
 | 
			
		||||
                total -= 1   
 | 
			
		||||
                skipped.append(combo)
 | 
			
		||||
                
 | 
			
		||||
    rel_log.info(" SUMMARY OF COMPILATION RESULTS")                
 | 
			
		||||
    rel_log.info(" ------------------------------")                
 | 
			
		||||
    rel_log.info(" NUMBER OF TEST APPS: %d, NUMBER OF TARGETS: %d", 
 | 
			
		||||
                 len(tests), len(supported_targets))   
 | 
			
		||||
    log_results(failures, " FAILED")
 | 
			
		||||
    log_results(skipped, " SKIPPED")
 | 
			
		||||
 | 
			
		||||
    # Output a % pass rate, indicate a failure if not 100% successful
 | 
			
		||||
    pass_rate = (float(passes) / float(total)) * 100.0
 | 
			
		||||
    rel_log.info(" PASS RATE %.1f %%\n", pass_rate)
 | 
			
		||||
    sys.exit(not (pass_rate == 100))
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2015 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
| 
						 | 
				
			
			@ -1,69 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2015 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    from colorama import Fore
 | 
			
		||||
except:
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
COLORAMA = 'colorama' in sys.modules
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IOperTestCaseBase():
 | 
			
		||||
    """ Interoperability test case base class
 | 
			
		||||
        @return list of tuple (severity, Description)
 | 
			
		||||
                Example:      (result.append((IOperTestSeverity.INFO, ""))
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        self.PASS = 'PASS'
 | 
			
		||||
        self.INFO = 'INFO'
 | 
			
		||||
        self.ERROR = 'ERROR'
 | 
			
		||||
        self.WARN = 'WARN'
 | 
			
		||||
 | 
			
		||||
        self.scope = scope   # Default test scope (basic, pedantic, mbed-enabled etc...)
 | 
			
		||||
 | 
			
		||||
    def test(self, param=None):
 | 
			
		||||
        result = []
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def RED(self, text):
 | 
			
		||||
        return self.color_text(text, color=Fore.RED, delim=Fore.RESET) if COLORAMA else text
 | 
			
		||||
 | 
			
		||||
    def GREEN(self, text):
 | 
			
		||||
        return self.color_text(text, color=Fore.GREEN, delim=Fore.RESET) if COLORAMA else text
 | 
			
		||||
 | 
			
		||||
    def YELLOW(self, text):
 | 
			
		||||
        return self.color_text(text, color=Fore.YELLOW, delim=Fore.RESET) if COLORAMA else text
 | 
			
		||||
 | 
			
		||||
    def color_text(self, text, color='', delim=''):
 | 
			
		||||
        return color + text + color + delim
 | 
			
		||||
 | 
			
		||||
    def COLOR(self, severity, text):
 | 
			
		||||
        colors = {
 | 
			
		||||
            self.PASS : self.GREEN,
 | 
			
		||||
            self.ERROR : self.RED,
 | 
			
		||||
            self.WARN : self.YELLOW
 | 
			
		||||
        }
 | 
			
		||||
        if severity in colors:
 | 
			
		||||
            return colors[severity](text)
 | 
			
		||||
        return text
 | 
			
		||||
| 
						 | 
				
			
			@ -1,125 +0,0 @@
 | 
			
		|||
#!/usr/bin/env python2
 | 
			
		||||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2015 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import mbed_lstools
 | 
			
		||||
from prettytable import PrettyTable
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    from colorama import init
 | 
			
		||||
except:
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
COLORAMA = 'colorama' in sys.modules
 | 
			
		||||
 | 
			
		||||
from ioper_base import IOperTestCaseBase
 | 
			
		||||
from ioper_test_fs import IOperTest_FileStructure_Basic
 | 
			
		||||
from ioper_test_fs import IOperTest_FileStructure_MbedEnabled
 | 
			
		||||
from ioper_test_target_id import IOperTest_TargetID_Basic
 | 
			
		||||
from ioper_test_target_id import IOperTest_TargetID_MbedEnabled
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TEST_LIST = [IOperTest_TargetID_Basic('basic'),
 | 
			
		||||
             IOperTest_TargetID_MbedEnabled('mbed-enabled'),
 | 
			
		||||
             IOperTest_FileStructure_Basic('basic'),
 | 
			
		||||
             IOperTest_FileStructure_MbedEnabled('mbed-enabled'),
 | 
			
		||||
             IOperTestCaseBase('all'),  # Dummy used to add 'all' option
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IOperTestRunner():
 | 
			
		||||
    """ Calls all i/face interoperability tests
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        """ Test scope:
 | 
			
		||||
            'pedantic' - all
 | 
			
		||||
            'mbed-enabled' - let's try to check if this device is mbed-enabled
 | 
			
		||||
            'basic' - just simple, passive tests (no device flashing)
 | 
			
		||||
        """
 | 
			
		||||
        self.requested_scope = scope    # Test scope given by user
 | 
			
		||||
        self.raw_test_results = {}      # Raw test results, can be used by exporters: { Platform: [test results]} 
 | 
			
		||||
 | 
			
		||||
        # Test scope definitions
 | 
			
		||||
        self.SCOPE_BASIC = 'basic'                  # Basic tests, sanity checks
 | 
			
		||||
        self.SCOPE_MBED_ENABLED = 'mbed-enabled'    # Let's try to check if this device is mbed-enabled
 | 
			
		||||
        self.SCOPE_PEDANTIC = 'pedantic'            # Extensive tests
 | 
			
		||||
        self.SCOPE_ALL = 'all'                      # All tests, equal to highest scope level
 | 
			
		||||
 | 
			
		||||
        # This structure will help us sort test scopes so we can include them
 | 
			
		||||
        # e.g. pedantic also includes basic and mbed-enabled tests
 | 
			
		||||
        self.scopes = {self.SCOPE_BASIC : 0,
 | 
			
		||||
                       self.SCOPE_MBED_ENABLED : 1,
 | 
			
		||||
                       self.SCOPE_PEDANTIC : 2,
 | 
			
		||||
                       self.SCOPE_ALL : 99,
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
        if COLORAMA:
 | 
			
		||||
            init()  # colorama.init()
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        """ Run tests, calculate overall score and print test results
 | 
			
		||||
        """
 | 
			
		||||
        mbeds = mbed_lstools.create()
 | 
			
		||||
        muts_list = mbeds.list_mbeds()
 | 
			
		||||
        test_base = IOperTestCaseBase()
 | 
			
		||||
 | 
			
		||||
        self.raw_test_results = {}
 | 
			
		||||
        for i, mut in enumerate(muts_list):
 | 
			
		||||
            result = []
 | 
			
		||||
            self.raw_test_results[mut['platform_name']] = []
 | 
			
		||||
 | 
			
		||||
            print "MBEDLS: Detected %s, port: %s, mounted: %s"% (mut['platform_name'],
 | 
			
		||||
                                                                 mut['serial_port'],
 | 
			
		||||
                                                                 mut['mount_point'])
 | 
			
		||||
            print "Running interoperability test suite, scope '%s'" % (self.requested_scope)
 | 
			
		||||
            for test_case in TEST_LIST:
 | 
			
		||||
                if self.scopes[self.requested_scope] >= self.scopes[test_case.scope]:
 | 
			
		||||
                    res = test_case.test(param=mut)
 | 
			
		||||
                    result.extend(res)
 | 
			
		||||
                    self.raw_test_results[mut['platform_name']].extend(res)
 | 
			
		||||
 | 
			
		||||
            columns = ['Platform', 'Test Case', 'Result', 'Scope', 'Description']
 | 
			
		||||
            pt = PrettyTable(columns)
 | 
			
		||||
            for col in columns:
 | 
			
		||||
                pt.align[col] = 'l'
 | 
			
		||||
 | 
			
		||||
            for tr in result:
 | 
			
		||||
                severity, tr_name, tr_scope, text = tr
 | 
			
		||||
                tr = (test_base.COLOR(severity, mut['platform_name']),
 | 
			
		||||
                      test_base.COLOR(severity, tr_name),
 | 
			
		||||
                      test_base.COLOR(severity, severity),
 | 
			
		||||
                      test_base.COLOR(severity, tr_scope),
 | 
			
		||||
                      test_base.COLOR(severity, text))
 | 
			
		||||
                pt.add_row(list(tr))
 | 
			
		||||
            print pt.get_string(border=True, sortby='Result')
 | 
			
		||||
            if i + 1 < len(muts_list):
 | 
			
		||||
                print
 | 
			
		||||
        return self.raw_test_results
 | 
			
		||||
 | 
			
		||||
def get_available_oper_test_scopes():
 | 
			
		||||
    """ Get list of available test scopes
 | 
			
		||||
    """
 | 
			
		||||
    scopes = set()
 | 
			
		||||
    for oper_test in TEST_LIST:
 | 
			
		||||
        if oper_test.scope is not None:
 | 
			
		||||
            scopes.add(oper_test.scope)
 | 
			
		||||
    return list(scopes)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,69 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2015 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import os.path
 | 
			
		||||
from ioper_base import IOperTestCaseBase
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IOperTest_FileStructure(IOperTestCaseBase):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        IOperTestCaseBase.__init__(self, scope)
 | 
			
		||||
 | 
			
		||||
    def if_file_exist(self, fname, fail_severity=None):
 | 
			
		||||
        file_path = os.path.join(self.param['mount_point'], fname)
 | 
			
		||||
        exist = os.path.isfile(file_path)
 | 
			
		||||
        tr_name = "FILE_EXIST(%s)" % fname.upper()
 | 
			
		||||
        if exist:
 | 
			
		||||
            self.result.append((self.PASS, tr_name, self.scope, "File '%s' exists" % file_path))
 | 
			
		||||
        else:
 | 
			
		||||
            self.result.append((fail_severity if fail_severity else self.ERROR, tr_name, self.scope, "File '%s' not found" % file_path))
 | 
			
		||||
 | 
			
		||||
    def test(self, param=None):
 | 
			
		||||
        self.result = []
 | 
			
		||||
        if param:
 | 
			
		||||
            pass
 | 
			
		||||
        return self.result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IOperTest_FileStructure_Basic(IOperTest_FileStructure):
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        IOperTest_FileStructure.__init__(self, scope)
 | 
			
		||||
 | 
			
		||||
    def test(self, param=None):
 | 
			
		||||
        self.param = param
 | 
			
		||||
        self.result = []
 | 
			
		||||
        if param:
 | 
			
		||||
            self.if_file_exist('mbed.htm', self.ERROR)
 | 
			
		||||
        return self.result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IOperTest_FileStructure_MbedEnabled(IOperTest_FileStructure):
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        IOperTest_FileStructure.__init__(self, scope)
 | 
			
		||||
 | 
			
		||||
    def test(self, param=None):
 | 
			
		||||
        self.param = param
 | 
			
		||||
        self.result = []
 | 
			
		||||
        if param:
 | 
			
		||||
            self.if_file_exist('mbed.htm', self.ERROR)
 | 
			
		||||
            self.if_file_exist('DETAILS.TXT', self.ERROR)
 | 
			
		||||
            self.if_file_exist('FAIL.TXT', self.INFO)
 | 
			
		||||
        return self.result
 | 
			
		||||
| 
						 | 
				
			
			@ -1,111 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2015 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from ioper_base import IOperTestCaseBase
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IOperTest_TargetID(IOperTestCaseBase):
 | 
			
		||||
    """ tests related to target_id value
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        IOperTestCaseBase.__init__(self, scope)
 | 
			
		||||
        self.TARGET_ID_LEN = 24
 | 
			
		||||
 | 
			
		||||
    def test_target_id_format(self, target_id, target_id_name):
 | 
			
		||||
        # Expected length == 24, eg. "02400203D94B0E7724B7F3CF"
 | 
			
		||||
        result = []
 | 
			
		||||
        target_id_len = len(target_id) if target_id else 0
 | 
			
		||||
        if target_id_len == self.TARGET_ID_LEN:
 | 
			
		||||
            result.append((self.PASS, "TARGET_ID_LEN", self.scope, "%s '%s' is %d chars long " % (target_id_name, target_id, target_id_len)))
 | 
			
		||||
            result.append((self.INFO, "FW_VER_STR", self.scope, "%s Version String is %s.%s.%s " % (target_id_name,
 | 
			
		||||
                                                                                      target_id[0:4],
 | 
			
		||||
                                                                                      target_id[4:8],
 | 
			
		||||
                                                                                      target_id[8:24],
 | 
			
		||||
                                                                                      )))
 | 
			
		||||
        else:
 | 
			
		||||
            result.append((self.ERROR, "TARGET_ID_LEN", self.scope, "%s '%s' is %d chars long. Expected %d chars" % (target_id_name, target_id, target_id_len, self.TARGET_ID_LEN)))
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def test_decode_target_id(self, target_id, target_id_name):
 | 
			
		||||
        result = []
 | 
			
		||||
        target_id_len = len(target_id) if target_id else 0
 | 
			
		||||
        if target_id_len >= 4:
 | 
			
		||||
            result.append((self.INFO, "FW_VEN_CODE", self.scope, "%s Vendor Code is '%s'" % (target_id_name, target_id[0:2])))
 | 
			
		||||
            result.append((self.INFO, "FW_PLAT_CODE", self.scope, "%s Platform Code is '%s'" % (target_id_name, target_id[2:4])))
 | 
			
		||||
            result.append((self.INFO, "FW_VER", self.scope, "%s Firmware Version is '%s'" % (target_id_name, target_id[4:8])))
 | 
			
		||||
            result.append((self.INFO, "FW_HASH_SEC", self.scope, "%s Hash of secret is '%s'" % (target_id_name, target_id[8:24])))
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def test(self, param=None):
 | 
			
		||||
        result = []
 | 
			
		||||
        if param:
 | 
			
		||||
            pass
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IOperTest_TargetID_Basic(IOperTest_TargetID):
 | 
			
		||||
    """ Basic interoperability tests checking TargetID compliance
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        IOperTest_TargetID.__init__(self, scope)
 | 
			
		||||
 | 
			
		||||
    def test(self, param=None):
 | 
			
		||||
        result = []
 | 
			
		||||
 | 
			
		||||
        if param:
 | 
			
		||||
            result.append((self.PASS, "TARGET_ID", self.scope, "TargetID '%s' found" % param['target_id']))
 | 
			
		||||
 | 
			
		||||
            # Check if target name can be decoded with mbed-ls
 | 
			
		||||
            if param['platform_name']:
 | 
			
		||||
                result.append((self.PASS, "TARGET_ID_DECODE", self.scope, "TargetID '%s' decoded as '%s'" % (param['target_id'][0:4], param['platform_name'])))
 | 
			
		||||
            else:
 | 
			
		||||
                result.append((self.ERROR, "TARGET_ID_DECODE", self.scope, "TargetID '%s'... not decoded" % (param['target_id'] if param['target_id'] else '')))
 | 
			
		||||
 | 
			
		||||
            # Test for USBID and mbed.htm consistency
 | 
			
		||||
            if param['target_id_mbed_htm'] == param['target_id_usb_id']:
 | 
			
		||||
                result.append((self.PASS, "TARGET_ID_MATCH", self.scope, "TargetID (USBID) and TargetID (mbed.htm) match"))
 | 
			
		||||
            else:
 | 
			
		||||
                text = "TargetID (USBID) and TargetID (mbed.htm) don't match: '%s' != '%s'" % (param['target_id_usb_id'], param['target_id_mbed_htm'])
 | 
			
		||||
                result.append((self.WARN, "TARGET_ID_MATCH", self.scope, text))
 | 
			
		||||
        else:
 | 
			
		||||
            result.append((self.ERROR, "TARGET_ID", self.scope, "TargetID not found"))
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
class IOperTest_TargetID_MbedEnabled(IOperTest_TargetID):
 | 
			
		||||
    """ Basic interoperability tests checking TargetID compliance
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, scope=None):
 | 
			
		||||
        IOperTest_TargetID.__init__(self, scope)
 | 
			
		||||
 | 
			
		||||
    def test(self, param=None):
 | 
			
		||||
        result = []
 | 
			
		||||
 | 
			
		||||
        if param:
 | 
			
		||||
            # Target ID tests:
 | 
			
		||||
            result += self.test_target_id_format(param['target_id_usb_id'], "TargetId (USBID)")
 | 
			
		||||
            result += self.test_target_id_format(param['target_id_mbed_htm'], "TargetId (mbed.htm)")
 | 
			
		||||
 | 
			
		||||
            # Some extra info about TargetID itself
 | 
			
		||||
            result += self.test_decode_target_id(param['target_id_usb_id'], "TargetId (USBID)")
 | 
			
		||||
            result += self.test_decode_target_id(param['target_id_mbed_htm'], "TargetId (mbed.htm)")
 | 
			
		||||
        return result
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
| 
						 | 
				
			
			@ -1,34 +0,0 @@
 | 
			
		|||
/* mbed Microcontroller Library
 | 
			
		||||
 * Copyright (c) 2006-2012 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef MBED_CLASSES_H
 | 
			
		||||
#define MBED_CLASSES_H
 | 
			
		||||
 | 
			
		||||
#include "rpc.h"
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
{{classes}}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,24 +0,0 @@
 | 
			
		|||
class Rpc{{name}} : public RPC {
 | 
			
		||||
public:
 | 
			
		||||
    Rpc{{name}}({{cons_proto}}) : RPC(name), o({{cons_call}}) {}
 | 
			
		||||
 | 
			
		||||
    {{methods}}
 | 
			
		||||
 | 
			
		||||
    virtual const struct rpc_method *get_rpc_methods() {
 | 
			
		||||
        static const rpc_method rpc_methods[] = {
 | 
			
		||||
            {{rpc_methods}},
 | 
			
		||||
            RPC_METHOD_SUPER(RPC)
 | 
			
		||||
        };
 | 
			
		||||
        return rpc_methods;
 | 
			
		||||
    }
 | 
			
		||||
    static struct rpc_class *get_rpc_class() {
 | 
			
		||||
        static const rpc_function funcs[] = {
 | 
			
		||||
            {"new", rpc_function_caller<const char*, {{cons_type}}, &RPC::construct<Rpc{{name}}, {{cons_type}}> >},
 | 
			
		||||
            RPC_METHOD_END
 | 
			
		||||
        };
 | 
			
		||||
        static rpc_class c = {"{{name}}", funcs, NULL};
 | 
			
		||||
        return &c;
 | 
			
		||||
    }
 | 
			
		||||
private:
 | 
			
		||||
    {{name}} o;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
from tools.targets import TARGETS
 | 
			
		||||
 | 
			
		||||
DEFAULT_SUPPORT = {}
 | 
			
		||||
CORTEX_ARM_SUPPORT = {}
 | 
			
		||||
 | 
			
		||||
for target in TARGETS:
 | 
			
		||||
    DEFAULT_SUPPORT[target.name] = target.supported_toolchains
 | 
			
		||||
 | 
			
		||||
    if target.core.startswith('Cortex'):
 | 
			
		||||
        CORTEX_ARM_SUPPORT[target.name] = [t for t in target.supported_toolchains
 | 
			
		||||
                                           if (t=='ARM' or t=='uARM')]
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
| 
						 | 
				
			
			@ -1,89 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
from numpy import sin, arange, pi
 | 
			
		||||
from scipy.signal import lfilter, firwin
 | 
			
		||||
from pylab import figure, plot, grid, show
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
# Create a signal for demonstration.
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
# 320 samples of (1000Hz + 15000 Hz) at 48 kHz
 | 
			
		||||
sample_rate = 48000.
 | 
			
		||||
nsamples = 320
 | 
			
		||||
 | 
			
		||||
F_1KHz = 1000.
 | 
			
		||||
A_1KHz = 1.0
 | 
			
		||||
 | 
			
		||||
F_15KHz = 15000.
 | 
			
		||||
A_15KHz = 0.5
 | 
			
		||||
 | 
			
		||||
t = arange(nsamples) / sample_rate
 | 
			
		||||
signal = A_1KHz * sin(2*pi*F_1KHz*t) + A_15KHz*sin(2*pi*F_15KHz*t)
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
# Create a FIR filter and apply it to signal.
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
# The Nyquist rate of the signal.
 | 
			
		||||
nyq_rate = sample_rate / 2.
 | 
			
		||||
 | 
			
		||||
# The cutoff frequency of the filter: 6KHz
 | 
			
		||||
cutoff_hz = 6000.0
 | 
			
		||||
 | 
			
		||||
# Length of the filter (number of coefficients, i.e. the filter order + 1)
 | 
			
		||||
numtaps = 29
 | 
			
		||||
 | 
			
		||||
# Use firwin to create a lowpass FIR filter
 | 
			
		||||
fir_coeff = firwin(numtaps, cutoff_hz/nyq_rate)
 | 
			
		||||
 | 
			
		||||
# Use lfilter to filter the signal with the FIR filter
 | 
			
		||||
filtered_signal = lfilter(fir_coeff, 1.0, signal)
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
# Plot the original and filtered signals.
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
 | 
			
		||||
# The first N-1 samples are "corrupted" by the initial conditions
 | 
			
		||||
warmup = numtaps - 1
 | 
			
		||||
 | 
			
		||||
# The phase delay of the filtered signal
 | 
			
		||||
delay = (warmup / 2) / sample_rate
 | 
			
		||||
 | 
			
		||||
figure(1)
 | 
			
		||||
# Plot the original signal
 | 
			
		||||
plot(t, signal)
 | 
			
		||||
 | 
			
		||||
# Plot the filtered signal, shifted to compensate for the phase delay
 | 
			
		||||
plot(t-delay, filtered_signal, 'r-')
 | 
			
		||||
 | 
			
		||||
# Plot just the "good" part of the filtered signal.  The first N-1
 | 
			
		||||
# samples are "corrupted" by the initial conditions.
 | 
			
		||||
plot(t[warmup:]-delay, filtered_signal[warmup:], 'g', linewidth=4)
 | 
			
		||||
 | 
			
		||||
grid(True)
 | 
			
		||||
 | 
			
		||||
show()
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
# Print values
 | 
			
		||||
#------------------------------------------------
 | 
			
		||||
def print_values(label, values):
 | 
			
		||||
    var = "float32_t %s[%d]" % (label, len(values))
 | 
			
		||||
    print "%-30s = {%s}" % (var, ', '.join(["%+.10f" % x for x in values]))
 | 
			
		||||
 | 
			
		||||
print_values('signal', signal)
 | 
			
		||||
print_values('fir_coeff', fir_coeff)
 | 
			
		||||
print_values('filtered_signal', filtered_signal)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright (c) 2014-2019 ARM Limited. All rights reserved.
 | 
			
		||||
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from intelhex import IntelHex
 | 
			
		||||
from cStringIO import StringIO
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def sections(h):
 | 
			
		||||
    start, last_address = None, None
 | 
			
		||||
    for a in h.addresses():
 | 
			
		||||
        if last_address is None:
 | 
			
		||||
            start, last_address = a, a
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        if a > last_address + 1:
 | 
			
		||||
            yield (start, last_address)
 | 
			
		||||
            start = a
 | 
			
		||||
 | 
			
		||||
        last_address = a
 | 
			
		||||
 | 
			
		||||
    if start:
 | 
			
		||||
        yield (start, last_address)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def print_sections(h):
 | 
			
		||||
    for s in sections(h):
 | 
			
		||||
        print "[0x%08X - 0x%08X]" % s
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def decode(record):
 | 
			
		||||
    h = IntelHex()
 | 
			
		||||
    f = StringIO(record)
 | 
			
		||||
    h.loadhex(f)
 | 
			
		||||
    h.dump()
 | 
			
		||||
| 
						 | 
				
			
			@ -1,190 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
"""
 | 
			
		||||
from os.path import join
 | 
			
		||||
from jinja2 import Template
 | 
			
		||||
 | 
			
		||||
from tools.paths import TOOLS_DATA, MBED_RPC
 | 
			
		||||
 | 
			
		||||
RPC_TEMPLATES_PATH = join(TOOLS_DATA, "rpc")
 | 
			
		||||
 | 
			
		||||
RPC_TEMPLATE = "RPCClasses.h"
 | 
			
		||||
CLASS_TEMPLATE = "class.cpp"
 | 
			
		||||
RPC_CLASSES_PATH = join(MBED_RPC, RPC_TEMPLATE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_template(name):
 | 
			
		||||
    return Template(open(join(RPC_TEMPLATES_PATH, name)).read())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def write_rpc_classes(classes):
 | 
			
		||||
    template = get_template(RPC_TEMPLATE)
 | 
			
		||||
    open(RPC_CLASSES_PATH, "w").write(template.render({"classes":classes}))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
RPC_CLASSES = (
 | 
			
		||||
    {
 | 
			
		||||
        "name": "DigitalOut",
 | 
			
		||||
        "cons_args": ["PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            (None , "write", ["int"]),
 | 
			
		||||
            ("int", "read" , []),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "DigitalIn",
 | 
			
		||||
        "cons_args": ["PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            ("int", "read" , []),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "DigitalInOut",
 | 
			
		||||
        "cons_args": ["PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            ("int", "read"  , []),
 | 
			
		||||
            (None , "write" , ["int"]),
 | 
			
		||||
            (None , "input" , []),
 | 
			
		||||
            (None , "output", []),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "AnalogIn",
 | 
			
		||||
        "required": "ANALOGIN",
 | 
			
		||||
        "cons_args": ["PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            ("float"         , "read"    , []),
 | 
			
		||||
            ("unsigned short", "read_u16", []),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "AnalogOut",
 | 
			
		||||
        "required": "ANALOGOUT",
 | 
			
		||||
        "cons_args": ["PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            ("float", "read"     , []),
 | 
			
		||||
            (None   , "write"    , ["float"]),
 | 
			
		||||
            (None   , "write_u16", ["unsigned short"]),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "PwmOut",
 | 
			
		||||
        "required": "PWMOUT",
 | 
			
		||||
        "cons_args": ["PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            ("float", "read"         , []),
 | 
			
		||||
            (None   , "write"        , ["float"]),
 | 
			
		||||
            (None   , "period"       , ["float"]),
 | 
			
		||||
            (None   , "period_ms"    , ["int"]),
 | 
			
		||||
            (None   , "pulsewidth"   , ["float"]),
 | 
			
		||||
            (None   , "pulsewidth_ms", ["int"]),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "SPI",
 | 
			
		||||
        "required": "SPI",
 | 
			
		||||
        "cons_args": ["PinName", "PinName", "PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            (None , "format"   , ["int", "int"]),
 | 
			
		||||
            (None , "frequency", ["int"]),
 | 
			
		||||
            ("int", "write"    , ["int"]),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "Serial",
 | 
			
		||||
        "required": "SERIAL",
 | 
			
		||||
        "cons_args": ["PinName", "PinName"],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            (None , "baud"     , ["int"]),
 | 
			
		||||
            ("int", "readable" , []),
 | 
			
		||||
            ("int", "writeable", []),
 | 
			
		||||
            ("int", "putc"     , ["int"]),
 | 
			
		||||
            ("int", "getc"     , []),
 | 
			
		||||
            ("int", "puts"     , ["const char *"]),
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        "name": "Timer",
 | 
			
		||||
        "cons_args": [],
 | 
			
		||||
        "methods": [
 | 
			
		||||
            (None   , "start"  , []),
 | 
			
		||||
            (None   , "stop"   , []),
 | 
			
		||||
            (None   , "reset"  , []),
 | 
			
		||||
            ("float", "read"   , []),
 | 
			
		||||
            ("int"  , "read_ms", []),
 | 
			
		||||
            ("int"  , "read_us", []),
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_args_proto(args_types, extra=None):
 | 
			
		||||
    args = ["%s a%d" % (s, n) for n, s in enumerate(args_types)]
 | 
			
		||||
    if extra:
 | 
			
		||||
        args.extend(extra)
 | 
			
		||||
    return ', '.join(args)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_args_call(args):
 | 
			
		||||
    return ', '.join(["a%d"    % (n)    for n in range(len(args))])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = []
 | 
			
		||||
class_template = get_template(CLASS_TEMPLATE)
 | 
			
		||||
 | 
			
		||||
for c in RPC_CLASSES:
 | 
			
		||||
    c_args = c['cons_args']
 | 
			
		||||
    data = {
 | 
			
		||||
        'name': c['name'],
 | 
			
		||||
        'cons_type': ', '.join(c_args + ['const char*']),
 | 
			
		||||
        "cons_proto": get_args_proto(c_args, ["const char *name=NULL"]),
 | 
			
		||||
        "cons_call": get_args_call(c_args)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    c_name = "Rpc" +  c['name']
 | 
			
		||||
 | 
			
		||||
    methods = []
 | 
			
		||||
    rpc_methods = []
 | 
			
		||||
    for r, m, a in c['methods']:
 | 
			
		||||
        ret_proto = r if r else "void"
 | 
			
		||||
        args_proto = "void"
 | 
			
		||||
 | 
			
		||||
        ret_defin = "return " if r else ""
 | 
			
		||||
        args_defin = ""
 | 
			
		||||
 | 
			
		||||
        if a:
 | 
			
		||||
            args_proto = get_args_proto(a)
 | 
			
		||||
            args_defin = get_args_call(a)
 | 
			
		||||
 | 
			
		||||
        proto = "%s %s(%s)"   % (ret_proto, m, args_proto)
 | 
			
		||||
        defin = "{%so.%s(%s);}" % (ret_defin, m, args_defin)
 | 
			
		||||
        methods.append("%s %s" % (proto, defin))
 | 
			
		||||
 | 
			
		||||
        rpc_method_type = [r] if r else []
 | 
			
		||||
        rpc_method_type.append(c_name)
 | 
			
		||||
        rpc_method_type.extend(a)
 | 
			
		||||
        rpc_methods.append('{"%s", rpc_method_caller<%s, &%s::%s>}' % (m, ', '.join(rpc_method_type), c_name, m))
 | 
			
		||||
 | 
			
		||||
    data['methods'] = "\n    ".join(methods)
 | 
			
		||||
    data['rpc_methods'] = ",\n            ".join(rpc_methods)
 | 
			
		||||
 | 
			
		||||
    class_decl = class_template.render(data)
 | 
			
		||||
    if 'required' in c:
 | 
			
		||||
        class_decl = "#if DEVICE_%s\n%s\n#endif" % (c['required'], class_decl)
 | 
			
		||||
 | 
			
		||||
    classes.append(class_decl)
 | 
			
		||||
 | 
			
		||||
write_rpc_classes('\n\n'.join(classes))
 | 
			
		||||
| 
						 | 
				
			
			@ -1,75 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Utility to find which libraries could define a given symbol
 | 
			
		||||
"""
 | 
			
		||||
from argparse import ArgumentParser
 | 
			
		||||
from os.path import join, splitext
 | 
			
		||||
from os import walk
 | 
			
		||||
from subprocess import Popen, PIPE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
OBJ_EXT = ['.o', '.a', '.ar']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def find_sym_in_lib(sym, obj_path):
 | 
			
		||||
    contain_symbol = False
 | 
			
		||||
 | 
			
		||||
    out = Popen(["nm", "-C", obj_path], stdout=PIPE, stderr=PIPE).communicate()[0]
 | 
			
		||||
    for line in out.splitlines():
 | 
			
		||||
            tokens = line.split()
 | 
			
		||||
            n = len(tokens)
 | 
			
		||||
            if n == 2:
 | 
			
		||||
                sym_type = tokens[0]
 | 
			
		||||
                sym_name = tokens[1]
 | 
			
		||||
            elif n == 3:
 | 
			
		||||
                sym_type = tokens[1]
 | 
			
		||||
                sym_name = tokens[2]
 | 
			
		||||
            else:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            if sym_type == "U":
 | 
			
		||||
                # This object is using this symbol, not defining it
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            if sym_name == sym:
 | 
			
		||||
                contain_symbol = True
 | 
			
		||||
 | 
			
		||||
    return contain_symbol
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def find_sym_in_path(sym, dir_path):
 | 
			
		||||
    for root, _, files in walk(dir_path):
 | 
			
		||||
        for file in files:
 | 
			
		||||
 | 
			
		||||
            _, ext = splitext(file)
 | 
			
		||||
            if ext not in OBJ_EXT: continue
 | 
			
		||||
 | 
			
		||||
            path = join(root, file)
 | 
			
		||||
            if find_sym_in_lib(sym, path):
 | 
			
		||||
                print path
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    parser = ArgumentParser(description='Find Symbol')
 | 
			
		||||
    parser.add_argument('-s', '--sym',  required=True,
 | 
			
		||||
                        help='The symbol to be searched')
 | 
			
		||||
    parser.add_argument('-p', '--path',  required=True,
 | 
			
		||||
                        help='The path where to search')
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    find_sym_in_path(args.sym, args.path)
 | 
			
		||||
| 
						 | 
				
			
			@ -21,8 +21,7 @@ from tools.paths import MBED_LIBRARIES,\
 | 
			
		|||
    CPPUTEST_PLATFORM_SRC, CPPUTEST_TESTRUNNER_SCR, CPPUTEST_LIBRARY,\
 | 
			
		||||
    CPPUTEST_INC, CPPUTEST_PLATFORM_INC, CPPUTEST_TESTRUNNER_INC,\
 | 
			
		||||
    CPPUTEST_INC_EXT
 | 
			
		||||
from tools.data.support import DEFAULT_SUPPORT
 | 
			
		||||
from tools.tests import TEST_MBED_LIB
 | 
			
		||||
from tools.tests import TEST_MBED_LIB, DEFAULT_SUPPORT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LIBRARIES = [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,39 +0,0 @@
 | 
			
		|||
#!/usr/bin/env python
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
Copyright (c) 2016-2019 ARM Limited. All rights reserved.
 | 
			
		||||
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
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 os
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
def main(path='.', pattern=r'#include\s+"([^"]*\.(?:c|cpp))"'):
 | 
			
		||||
    pattern = re.compile(pattern)
 | 
			
		||||
 | 
			
		||||
    for root, dirs, files in os.walk(path, followlinks=True):
 | 
			
		||||
        for file in files:
 | 
			
		||||
            with open(os.path.join(root, file)) as f:
 | 
			
		||||
                for line in f.read().splitlines():
 | 
			
		||||
                    m = re.search(pattern, line)
 | 
			
		||||
                    if m:
 | 
			
		||||
                        print os.path.relpath(os.path.join(root, m.group(1)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    import sys
 | 
			
		||||
    main(*sys.argv[1:])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,234 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright (c) 2016-2019 ARM Limited. All rights reserved.
 | 
			
		||||
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
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 stat
 | 
			
		||||
import re
 | 
			
		||||
from collections import OrderedDict
 | 
			
		||||
from subprocess import Popen
 | 
			
		||||
 | 
			
		||||
git_processes = []
 | 
			
		||||
 | 
			
		||||
class MyJSONEncoder(json.JSONEncoder):
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(MyJSONEncoder, self).__init__(*args, **kwargs)
 | 
			
		||||
        self.current_indent = 0
 | 
			
		||||
        self.current_indent_str = ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def encode(self, o):
 | 
			
		||||
        #Special Processing for lists
 | 
			
		||||
        if isinstance(o, (list, tuple)):
 | 
			
		||||
            primitives_only = True
 | 
			
		||||
            for item in o:
 | 
			
		||||
                if isinstance(item, (list, tuple, dict)):
 | 
			
		||||
                    primitives_only = False
 | 
			
		||||
                    break
 | 
			
		||||
            output = []
 | 
			
		||||
            if primitives_only:
 | 
			
		||||
                for item in o:
 | 
			
		||||
                    output.append(json.dumps(item))
 | 
			
		||||
                return "[" + ", ".join(output) + "]"
 | 
			
		||||
            else:
 | 
			
		||||
                self.current_indent += self.indent
 | 
			
		||||
                self.current_indent_str = " " * self.current_indent
 | 
			
		||||
                for item in o:
 | 
			
		||||
                    output.append(self.current_indent_str + self.encode(item))
 | 
			
		||||
                self.current_indent -= self.indent
 | 
			
		||||
                self.current_indent_str = " " * self.current_indent
 | 
			
		||||
                return "[\n" + ",\n".join(output) + "\n" + self.current_indent_str + "]"
 | 
			
		||||
        elif isinstance(o, dict):
 | 
			
		||||
            primitives_only = True
 | 
			
		||||
            for item in o.values():
 | 
			
		||||
                if isinstance(item, (list, tuple, dict)):
 | 
			
		||||
                    primitives_only = False
 | 
			
		||||
                    break
 | 
			
		||||
            output = []
 | 
			
		||||
            if primitives_only and len(o) < 3:
 | 
			
		||||
                for key, value in o.items():
 | 
			
		||||
                    output.append(json.dumps(key) + ": " + self.encode(value))
 | 
			
		||||
                return "{" + ", ".join(output) + "}"
 | 
			
		||||
            else:
 | 
			
		||||
                self.current_indent += self.indent
 | 
			
		||||
                self.current_indent_str = " " * self.current_indent
 | 
			
		||||
                for key, value in o.items():
 | 
			
		||||
                    output.append(self.current_indent_str + json.dumps(key) + ": " + self.encode(value))
 | 
			
		||||
                self.current_indent -= self.indent
 | 
			
		||||
                self.current_indent_str = " " * self.current_indent
 | 
			
		||||
                return "{\n" + ",\n".join(output) + "\n" + self.current_indent_str + "}"
 | 
			
		||||
        else:
 | 
			
		||||
            return json.dumps(o)
 | 
			
		||||
 | 
			
		||||
def load(path):
 | 
			
		||||
    with open(path, 'r') as f :
 | 
			
		||||
        return json.load(f, object_pairs_hook=OrderedDict)
 | 
			
		||||
 | 
			
		||||
def dump(path, obj):
 | 
			
		||||
    with os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, stat.S_IRUSR | stat.S_IWUSR), 'w') as f :
 | 
			
		||||
        os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
 | 
			
		||||
        f.write(MyJSONEncoder(indent=4).encode(obj))
 | 
			
		||||
        f.write(u'\n')
 | 
			
		||||
        f.truncate()
 | 
			
		||||
 | 
			
		||||
def find(stem, path) :
 | 
			
		||||
    for root, directories, files in os.walk(path, followlinks=True) :
 | 
			
		||||
        [dir for dir in directories if dir[0] != '.']
 | 
			
		||||
        if (stem_match(stem,os.path.basename(os.path.normpath(root))) and
 | 
			
		||||
            "device.h" in files) :
 | 
			
		||||
            return os.path.join(root, "device.h")
 | 
			
		||||
 | 
			
		||||
def find_all_devices(path, verbose=False) :
 | 
			
		||||
    for root, directories, files in os.walk(path, followlinks=True) :
 | 
			
		||||
        [dir for dir in directories if dir[0] != '.']
 | 
			
		||||
        if "device.h" in files :
 | 
			
		||||
            if verbose : print("[VERBOSE] found a device.h file in {}".format(root))
 | 
			
		||||
            yield os.path.join(root, "device.h")
 | 
			
		||||
 | 
			
		||||
mbed_matcher = re.compile('mbed', re.IGNORECASE)
 | 
			
		||||
def stem_match(stem, thing) :
 | 
			
		||||
    return (stem in thing or
 | 
			
		||||
            re.sub(mbed_matcher, '', stem) in thing)
 | 
			
		||||
 | 
			
		||||
attr_matcher = re.compile('^#define\W+DEVICE_(\w+)\W+1.*$')
 | 
			
		||||
def parse_attributes(path) :
 | 
			
		||||
    with open(path) as input :
 | 
			
		||||
        for line in input :
 | 
			
		||||
            m = re.match(attr_matcher, line)
 | 
			
		||||
            if m: yield m.group(1)
 | 
			
		||||
 | 
			
		||||
remove_matcher = re.compile('^#define\W+DEVICE_(\w+)\W+[10].*$')
 | 
			
		||||
def remove_attributes(path) :
 | 
			
		||||
    with open(path) as input :
 | 
			
		||||
        remainder = filter(lambda l: not re.match(remove_matcher, l), input)
 | 
			
		||||
    with open(path,"wb") as output :
 | 
			
		||||
        output.truncate(0)
 | 
			
		||||
        output.write("// The 'provides' section in 'target.json' is now used"+
 | 
			
		||||
                     " to create the device's hardware preprocessor switches.\n")
 | 
			
		||||
        output.write("// Check the 'provides' section of the target description"+
 | 
			
		||||
                     " in 'targets.json' for more details.\n")
 | 
			
		||||
        output.writelines(remainder)
 | 
			
		||||
 | 
			
		||||
def user_select(things, message) :
 | 
			
		||||
    print(message)
 | 
			
		||||
    for thing, number in zip(things, range(len(things))):
 | 
			
		||||
        print("{} : {}".format(number, thing))
 | 
			
		||||
    selection = None
 | 
			
		||||
    while selection is None :
 | 
			
		||||
        print("please select an integer [0..{}] or specify all".format(len(things) - 1))
 | 
			
		||||
        try :
 | 
			
		||||
            i = raw_input()
 | 
			
		||||
            if i == "all" :
 | 
			
		||||
                selection = "all"
 | 
			
		||||
            else :
 | 
			
		||||
                selection = int(i)
 | 
			
		||||
                if (selection > len(things) or
 | 
			
		||||
                    selection < 0) :
 | 
			
		||||
                    print("selection {} out of range".format(selection))
 | 
			
		||||
                    selection = None
 | 
			
		||||
        except (ValueError, SyntaxError) :
 | 
			
		||||
            print("selection not understood")
 | 
			
		||||
    if selection == "all" :
 | 
			
		||||
        return things
 | 
			
		||||
    else :
 | 
			
		||||
        return [things[selection]]
 | 
			
		||||
 | 
			
		||||
target_matcher = re.compile("TARGET_")
 | 
			
		||||
def strip_target(str) :
 | 
			
		||||
    return re.sub(target_matcher, "", str)
 | 
			
		||||
 | 
			
		||||
def add_to_targets(targets, device_file, verbose=False, remove=False) :
 | 
			
		||||
    if verbose : print("[VERBOSE] trying target {}".format(device_file))
 | 
			
		||||
    device = strip_target(os.path.basename(os.path.normpath(os.path.dirname(device_file))))
 | 
			
		||||
    if not device :
 | 
			
		||||
        print("[WARNING] device {} did not have an associated device.h".format(device))
 | 
			
		||||
    else :
 | 
			
		||||
        possible_matches = set([key for key in targets.keys() if stem_match(device, key)])
 | 
			
		||||
        for key, value in targets.items() :
 | 
			
		||||
            for alt in value['extra_labels'] if 'extra_labels' in value else [] :
 | 
			
		||||
                if stem_match(device, alt) : possible_matches.add(key)
 | 
			
		||||
            for alt in value['extra_labels_add'] if 'extra_labels_add' in value else [] :
 | 
			
		||||
                if stem_match(device, alt) : possible_matches.add(key)
 | 
			
		||||
        possible_matches = list(possible_matches)
 | 
			
		||||
        for match in possible_matches :
 | 
			
		||||
            if device == match : possible_matches = [match]
 | 
			
		||||
        if not possible_matches :
 | 
			
		||||
            print("[WARNING] device {} did not have an associated entry in targets.json".format(device))
 | 
			
		||||
            return None
 | 
			
		||||
        elif len(possible_matches) > 1 :
 | 
			
		||||
            message = ("possible matches for file {}".format(device_file))
 | 
			
		||||
            target = user_select(possible_matches, message)
 | 
			
		||||
        else :
 | 
			
		||||
            target = possible_matches
 | 
			
		||||
        attrs = list(parse_attributes(device_file))
 | 
			
		||||
        if attrs :
 | 
			
		||||
            for t in target :
 | 
			
		||||
                targets[t]["device_has"] = sorted(list(set(targets[t].setdefault("device_has",[]) + attrs)))
 | 
			
		||||
                if verbose : print("[VERBOSE] target {} now device_has {}".format(t, attrs))
 | 
			
		||||
            if remove is True:
 | 
			
		||||
                remove_attributes(device_file)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__' :
 | 
			
		||||
    import argparse
 | 
			
		||||
    parser = argparse.ArgumentParser(description='A helpful little script for converting' +
 | 
			
		||||
                                     ' device.h files to parts of the targets.json file')
 | 
			
		||||
    parser.add_argument('-a', '--all', action='store_true',
 | 
			
		||||
                        help='find and convert all available device.h files in the'+
 | 
			
		||||
                        ' directory tree starting at the current directory')
 | 
			
		||||
    parser.add_argument('-f', '--file', nargs='+', help='specify an individual file to '+
 | 
			
		||||
                        'convert from device.h format to a piece of targets.json')
 | 
			
		||||
    parser.add_argument('-t', '--target', nargs='+', help='specify an individual target'+
 | 
			
		||||
                        ' to convert from device.h format to a piece of targets.json')
 | 
			
		||||
    parser.add_argument('-v', '--verbose', action='store_true',
 | 
			
		||||
                        help="print out every target that is updated in the targets.json")
 | 
			
		||||
    parser.add_argument('-r', '--rm', action='store_true',
 | 
			
		||||
                        help="remove the used attributes from a device.h file")
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
    if not args.target and not args.file and not args.all :
 | 
			
		||||
        print("[WARNING] no action specified; auto-formatting targets.json")
 | 
			
		||||
 | 
			
		||||
    targets_file_name = os.path.join(os.curdir, "hal", "targets.json")
 | 
			
		||||
    try :
 | 
			
		||||
        targets = load(targets_file_name)
 | 
			
		||||
    except OSError :
 | 
			
		||||
        print("[ERROR] did not find targets.json where I expected it {}".format(targets_file_name))
 | 
			
		||||
        exit(1)
 | 
			
		||||
    except ValueError :
 | 
			
		||||
        print("[ERROR] invalid json found in {}".format(targets_file_name))
 | 
			
		||||
        exit(2)
 | 
			
		||||
 | 
			
		||||
    if args.target :
 | 
			
		||||
        for target in args.target :
 | 
			
		||||
            device_file = find(target, os.curdir)
 | 
			
		||||
            if device_file :
 | 
			
		||||
                add_to_targets(targets, device_file, verbose=args.verbose, remove=args.rm)
 | 
			
		||||
            else :
 | 
			
		||||
                print("[WARNING] could not locate a device file for target {}".format(target))
 | 
			
		||||
 | 
			
		||||
    if args.file :
 | 
			
		||||
        for file in args.file :
 | 
			
		||||
            add_to_targets(targets, file, verbose=args.verbose, remove=args.rm)
 | 
			
		||||
 | 
			
		||||
    if args.all :
 | 
			
		||||
        for file in find_all_devices(os.curdir, verbose=args.verbose) :
 | 
			
		||||
            add_to_targets(targets, file, verbose=args.verbose, remove=args.rm)
 | 
			
		||||
 | 
			
		||||
    dump(targets_file_name, targets)
 | 
			
		||||
 | 
			
		||||
    for process in git_processes :
 | 
			
		||||
        process.wait()
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +65,6 @@ from tools.build_api import mcu_toolchain_matrix
 | 
			
		|||
# Imports from TEST API
 | 
			
		||||
from tools.test_api import SingleTestRunner
 | 
			
		||||
from tools.test_api import singletest_in_cli_mode
 | 
			
		||||
from tools.test_api import detect_database_verbose
 | 
			
		||||
from tools.test_api import get_json_data_from_file
 | 
			
		||||
from tools.test_api import get_avail_tests_summary_table
 | 
			
		||||
from tools.test_api import get_default_test_options_parser
 | 
			
		||||
| 
						 | 
				
			
			@ -109,10 +108,6 @@ if __name__ == '__main__':
 | 
			
		|||
        print "Version %d.%d"% get_version()
 | 
			
		||||
        exit(0)
 | 
			
		||||
 | 
			
		||||
    if opts.db_url and opts.verbose_test_configuration_only:
 | 
			
		||||
        detect_database_verbose(opts.db_url)
 | 
			
		||||
        exit(0)
 | 
			
		||||
 | 
			
		||||
    # Print summary / information about automation test status
 | 
			
		||||
    if opts.test_automation_report:
 | 
			
		||||
        print get_avail_tests_summary_table(platform_filter=opts.general_filter_regex)
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +222,6 @@ if __name__ == '__main__':
 | 
			
		|||
                                   _clean=opts.clean,
 | 
			
		||||
                                   _parser=parser,
 | 
			
		||||
                                   _opts=opts,
 | 
			
		||||
                                   _opts_db_url=opts.db_url,
 | 
			
		||||
                                   _opts_log_file_name=opts.log_file_name,
 | 
			
		||||
                                   _opts_report_html_file_name=opts.report_html_file_name,
 | 
			
		||||
                                   _opts_report_junit_file_name=opts.report_junit_file_name,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										121
									
								
								tools/size.py
								
								
								
								
							
							
						
						
									
										121
									
								
								tools/size.py
								
								
								
								
							| 
						 | 
				
			
			@ -1,121 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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 sys
 | 
			
		||||
from os.path import join, abspath, dirname, exists, splitext
 | 
			
		||||
from subprocess import Popen, PIPE
 | 
			
		||||
import csv
 | 
			
		||||
from collections import defaultdict
 | 
			
		||||
 | 
			
		||||
ROOT = abspath(join(dirname(__file__), ".."))
 | 
			
		||||
sys.path.insert(0, ROOT)
 | 
			
		||||
 | 
			
		||||
from tools.paths import BUILD_DIR, TOOLS_DATA
 | 
			
		||||
from tools.settings import GCC_ARM_PATH
 | 
			
		||||
from tools.tests import TEST_MAP
 | 
			
		||||
from tools.build_api import build_mbed_libs, build_project
 | 
			
		||||
 | 
			
		||||
SIZE = join(GCC_ARM_PATH, 'arm-none-eabi-size')
 | 
			
		||||
 | 
			
		||||
def get_size(path):
 | 
			
		||||
    out = Popen([SIZE, path], stdout=PIPE).communicate()[0]
 | 
			
		||||
    return map(int, out.splitlines()[1].split()[:4])
 | 
			
		||||
 | 
			
		||||
def get_percentage(before, after):
 | 
			
		||||
    if before == 0:
 | 
			
		||||
        return 0 if after == 0 else 100.0
 | 
			
		||||
    return float(after - before) / float(before) * 100.0
 | 
			
		||||
 | 
			
		||||
def human_size(val):
 | 
			
		||||
    if val>1024:
 | 
			
		||||
        return "%.0fKb" % (float(val)/1024.0)
 | 
			
		||||
    return "%d" % val
 | 
			
		||||
 | 
			
		||||
def print_diff(name, before, after):
 | 
			
		||||
    print "%s: (%s -> %s) %.2f%%" % (name, human_size(before) , human_size(after) , get_percentage(before , after))
 | 
			
		||||
 | 
			
		||||
BENCHMARKS = [
 | 
			
		||||
    ("BENCHMARK_1", "CENV"),
 | 
			
		||||
    ("BENCHMARK_2", "PRINTF"),
 | 
			
		||||
    ("BENCHMARK_3", "FP"),
 | 
			
		||||
    ("BENCHMARK_4", "MBED"),
 | 
			
		||||
    ("BENCHMARK_5", "ALL"),
 | 
			
		||||
]
 | 
			
		||||
BENCHMARK_DATA_PATH = join(TOOLS_DATA, 'benchmarks.csv')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def benchmarks():
 | 
			
		||||
    # CSV Data
 | 
			
		||||
    csv_data = csv.writer(open(BENCHMARK_DATA_PATH, 'wb'))
 | 
			
		||||
    csv_data.writerow(['Toolchain', "Target", "Benchmark", "code", "data", "bss", "flash"])
 | 
			
		||||
 | 
			
		||||
    # Build
 | 
			
		||||
    for toolchain in ['ARM', 'uARM', 'GCC_ARM']:
 | 
			
		||||
        for mcu in ["LPC1768", "LPC11U24"]:
 | 
			
		||||
            # Build Libraries
 | 
			
		||||
            build_mbed_libs(mcu, toolchain)
 | 
			
		||||
 | 
			
		||||
            # Build benchmarks
 | 
			
		||||
            build_dir = join(BUILD_DIR, "benchmarks", mcu, toolchain)
 | 
			
		||||
            for test_id, title in BENCHMARKS:
 | 
			
		||||
                # Build Benchmark
 | 
			
		||||
                try:
 | 
			
		||||
                    test = TEST_MAP[test_id]
 | 
			
		||||
                    path = build_project(test.source_dir, join(build_dir, test_id),
 | 
			
		||||
                                 mcu, toolchain, test.dependencies)
 | 
			
		||||
                    base, ext = splitext(path)
 | 
			
		||||
                    # Check Size
 | 
			
		||||
                    code, data, bss, flash = get_size(base+'.elf')
 | 
			
		||||
                    csv_data.writerow([toolchain, mcu, title, code, data, bss, flash])
 | 
			
		||||
                except Exception, e:
 | 
			
		||||
                    print "Unable to build %s for toolchain %s targeting %s" % (test_id, toolchain, mcu)
 | 
			
		||||
                    print e
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def compare(t1, t2, target):
 | 
			
		||||
    if not exists(BENCHMARK_DATA_PATH):
 | 
			
		||||
        benchmarks()
 | 
			
		||||
    else:
 | 
			
		||||
        print "Loading: %s" % BENCHMARK_DATA_PATH
 | 
			
		||||
 | 
			
		||||
    data = csv.reader(open(BENCHMARK_DATA_PATH, 'rb'))
 | 
			
		||||
 | 
			
		||||
    benchmarks_data = defaultdict(dict)
 | 
			
		||||
    for (toolchain, mcu, name, code, data, bss, flash) in data:
 | 
			
		||||
        if target == mcu:
 | 
			
		||||
            for t in [t1, t2]:
 | 
			
		||||
                if toolchain == t:
 | 
			
		||||
                    benchmarks_data[name][t] = map(int, (code, data, bss, flash))
 | 
			
		||||
 | 
			
		||||
    print "%s vs %s for %s" % (t1, t2, target)
 | 
			
		||||
    for name, data in benchmarks_data.items():
 | 
			
		||||
        try:
 | 
			
		||||
            # Check Size
 | 
			
		||||
            code_a, data_a, bss_a, flash_a = data[t1]
 | 
			
		||||
            code_u, data_u, bss_u, flash_u = data[t2]
 | 
			
		||||
 | 
			
		||||
            print "\n=== %s ===" % name
 | 
			
		||||
            print_diff("code", code_a , code_u)
 | 
			
		||||
            print_diff("data", data_a , data_u)
 | 
			
		||||
            print_diff("bss", bss_a , bss_u)
 | 
			
		||||
            print_diff("flash", flash_a , flash_u)
 | 
			
		||||
        except Exception, e:
 | 
			
		||||
            print "No data for benchmark %s" % (name)
 | 
			
		||||
            print e
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    compare("ARM", "GCC_ARM", "LPC1768")
 | 
			
		||||
							
								
								
									
										344
									
								
								tools/synch.py
								
								
								
								
							
							
						
						
									
										344
									
								
								tools/synch.py
								
								
								
								
							| 
						 | 
				
			
			@ -1,344 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
One repository to update them all
 | 
			
		||||
On mbed.org the mbed SDK is split up in multiple repositories, this script takes
 | 
			
		||||
care of updating them all.
 | 
			
		||||
"""
 | 
			
		||||
import sys
 | 
			
		||||
from copy import copy
 | 
			
		||||
from os import walk, remove, makedirs, getcwd, rmdir, listdir
 | 
			
		||||
from os.path import join, abspath, dirname, relpath, exists, isfile, normpath, isdir
 | 
			
		||||
from shutil import copyfile
 | 
			
		||||
from optparse import OptionParser
 | 
			
		||||
import re
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
ROOT = abspath(join(dirname(__file__), ".."))
 | 
			
		||||
sys.path.insert(0, ROOT)
 | 
			
		||||
 | 
			
		||||
from tools.settings import MBED_ORG_PATH, MBED_ORG_USER, BUILD_DIR
 | 
			
		||||
from tools.paths import *
 | 
			
		||||
from tools.utils import run_cmd
 | 
			
		||||
 | 
			
		||||
MBED_URL = "mbed.org"
 | 
			
		||||
MBED_USER = "mbed_official"
 | 
			
		||||
 | 
			
		||||
changed = []
 | 
			
		||||
push_remote = True
 | 
			
		||||
quiet = False
 | 
			
		||||
commit_msg = ''
 | 
			
		||||
 | 
			
		||||
# Code that does have a mirror in the mbed SDK
 | 
			
		||||
# Tuple data: (repo_name, list_of_code_dirs, [team])
 | 
			
		||||
# team is optional - if not specified, the code is published under mbed_official
 | 
			
		||||
OFFICIAL_CODE = {"mbed-dev" : ["cmsis", "drivers", "hal", "platform", "targets", "mbed.h"]}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# A list of regular expressions that will be checked against each directory
 | 
			
		||||
# name and skipped if they match.
 | 
			
		||||
IGNORE_DIRS = (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
IGNORE_FILES = (
 | 
			
		||||
    'COPYING',
 | 
			
		||||
    '\.md',
 | 
			
		||||
    "\.lib",
 | 
			
		||||
    "\.bld"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
def ignore_path(name, reg_exps):
 | 
			
		||||
    for r in reg_exps:
 | 
			
		||||
        if re.search(r, name):
 | 
			
		||||
            return True
 | 
			
		||||
    return False
 | 
			
		||||
 | 
			
		||||
class MbedRepository:
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def run_and_print(command, cwd):
 | 
			
		||||
        stdout, _, _ = run_cmd(command, work_dir=cwd, redirect=True)
 | 
			
		||||
        print(stdout)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, name):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.path = join(MBED_ORG_PATH, name)
 | 
			
		||||
        self.url = "http://" + MBED_URL + "/users/" + MBED_ORG_USER + "/code/%s/"
 | 
			
		||||
 | 
			
		||||
        if not exists(self.path):
 | 
			
		||||
            # Checkout code
 | 
			
		||||
            if not exists(MBED_ORG_PATH):
 | 
			
		||||
                makedirs(MBED_ORG_PATH)
 | 
			
		||||
 | 
			
		||||
            self.run_and_print(['hg', 'clone', self.url % name], cwd=MBED_ORG_PATH)
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            # Update
 | 
			
		||||
            self.run_and_print(['hg', 'pull'], cwd=self.path)
 | 
			
		||||
            self.run_and_print(['hg', 'update'], cwd=self.path)
 | 
			
		||||
 | 
			
		||||
    def publish(self):
 | 
			
		||||
        # The maintainer has to evaluate the changes first and explicitly accept them
 | 
			
		||||
        self.run_and_print(['hg', 'addremove'], cwd=self.path)
 | 
			
		||||
        stdout, _, _ = run_cmd(['hg', 'status'], work_dir=self.path)
 | 
			
		||||
        if stdout == '':
 | 
			
		||||
            print "No changes"
 | 
			
		||||
            return False
 | 
			
		||||
        print stdout
 | 
			
		||||
        if quiet:
 | 
			
		||||
            commit = 'Y'
 | 
			
		||||
        else:
 | 
			
		||||
            commit = raw_input(push_remote and "Do you want to commit and push? Y/N: " or "Do you want to commit? Y/N: ")
 | 
			
		||||
        if commit == 'Y':
 | 
			
		||||
            args = ['hg', 'commit', '-u', MBED_ORG_USER]
 | 
			
		||||
            
 | 
			
		||||
            
 | 
			
		||||
            # NOTE commit_msg should always come from the relevant mbed 2 release text
 | 
			
		||||
            if commit_msg:
 | 
			
		||||
                args = args + ['-m', commit_msg]
 | 
			
		||||
            self.run_and_print(args, cwd=self.path)
 | 
			
		||||
            if push_remote:
 | 
			
		||||
                self.run_and_print(['hg', 'push'], cwd=self.path)
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
# Check if a file is a text file or a binary file
 | 
			
		||||
# Taken from http://code.activestate.com/recipes/173220/
 | 
			
		||||
text_characters = "".join(map(chr, range(32, 127)) + list("\n\r\t\b"))
 | 
			
		||||
_null_trans = string.maketrans("", "")
 | 
			
		||||
def is_text_file(filename):
 | 
			
		||||
    block_size = 1024
 | 
			
		||||
    def istext(s):
 | 
			
		||||
        if "\0" in s:
 | 
			
		||||
            return 0
 | 
			
		||||
 | 
			
		||||
        if not s:  # Empty files are considered text
 | 
			
		||||
            return 1
 | 
			
		||||
 | 
			
		||||
        # Get the non-text characters (maps a character to itself then
 | 
			
		||||
        # use the 'remove' option to get rid of the text characters.)
 | 
			
		||||
        t = s.translate(_null_trans, text_characters)
 | 
			
		||||
 | 
			
		||||
        # If more than 30% non-text characters, then
 | 
			
		||||
        # this is considered a binary file
 | 
			
		||||
        if float(len(t))/len(s) > 0.30:
 | 
			
		||||
            return 0
 | 
			
		||||
        return 1
 | 
			
		||||
    with open(filename) as f:
 | 
			
		||||
        res = istext(f.read(block_size))
 | 
			
		||||
    return res
 | 
			
		||||
 | 
			
		||||
# Return the line ending type for the given file ('cr' or 'crlf')
 | 
			
		||||
def get_line_endings(f):
 | 
			
		||||
  examine_size = 1024
 | 
			
		||||
  try:
 | 
			
		||||
    tf = open(f, "rb")
 | 
			
		||||
    lines, ncrlf = tf.readlines(examine_size), 0
 | 
			
		||||
    tf.close()
 | 
			
		||||
    for l in lines:
 | 
			
		||||
      if l.endswith("\r\n"):
 | 
			
		||||
        ncrlf = ncrlf + 1
 | 
			
		||||
    return 'crlf' if ncrlf > len(lines) >> 1 else 'cr'
 | 
			
		||||
  except:
 | 
			
		||||
    return 'cr'
 | 
			
		||||
 | 
			
		||||
# Copy file to destination, but preserve destination line endings if possible
 | 
			
		||||
# This prevents very annoying issues with huge diffs that appear because of
 | 
			
		||||
# differences in line endings
 | 
			
		||||
def copy_with_line_endings(sdk_file, repo_file):
 | 
			
		||||
    if not isfile(repo_file):
 | 
			
		||||
        copyfile(sdk_file, repo_file)
 | 
			
		||||
        return
 | 
			
		||||
    is_text = is_text_file(repo_file)
 | 
			
		||||
    if is_text:
 | 
			
		||||
        sdk_le = get_line_endings(sdk_file)
 | 
			
		||||
        repo_le = get_line_endings(repo_file)
 | 
			
		||||
    if not is_text or sdk_le == repo_le:
 | 
			
		||||
        copyfile(sdk_file, repo_file)
 | 
			
		||||
    else:
 | 
			
		||||
        print "Converting line endings in '%s' to '%s'" % (abspath(repo_file), repo_le)
 | 
			
		||||
        f = open(sdk_file, "rb")
 | 
			
		||||
        data = f.read()
 | 
			
		||||
        f.close()
 | 
			
		||||
        f = open(repo_file, "wb")
 | 
			
		||||
        data = data.replace("\r\n", "\n") if repo_le == 'cr' else data.replace('\n','\r\n')
 | 
			
		||||
        f.write(data)
 | 
			
		||||
        f.close()
 | 
			
		||||
 | 
			
		||||
def visit_files(path, visit):
 | 
			
		||||
    for root, dirs, files in walk(path):    
 | 
			
		||||
        # Ignore hidden directories
 | 
			
		||||
        for d in copy(dirs):
 | 
			
		||||
            full = join(root, d)
 | 
			
		||||
            if d.startswith('.'):
 | 
			
		||||
                dirs.remove(d)
 | 
			
		||||
            if ignore_path(full, IGNORE_DIRS):
 | 
			
		||||
                print "Skipping '%s'" % full
 | 
			
		||||
                dirs.remove(d)
 | 
			
		||||
 | 
			
		||||
        for file in files:
 | 
			
		||||
            if ignore_path(file, IGNORE_FILES):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            visit(join(root, file))
 | 
			
		||||
 | 
			
		||||
def visit_dirs(path, visit):
 | 
			
		||||
 | 
			
		||||
    for root, dirs, files in walk(path, topdown=False):            
 | 
			
		||||
        for d in dirs:
 | 
			
		||||
            full = join(root, d)
 | 
			
		||||
            
 | 
			
		||||
            # We don't want to remove the .hg directory
 | 
			
		||||
            if not '.hg' in full:
 | 
			
		||||
                visit(full)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_repo(repo_name, sdk_paths, lib=False):
 | 
			
		||||
    repo = MbedRepository(repo_name)
 | 
			
		||||
    
 | 
			
		||||
    # copy files from mbed SDK to mbed_official repository
 | 
			
		||||
    def visit_mbed_sdk(sdk_file):
 | 
			
		||||
 | 
			
		||||
        # Source files structure is different for the compiled binary lib 
 | 
			
		||||
        # compared to the mbed-dev sources
 | 
			
		||||
        if lib:
 | 
			
		||||
            repo_file = join(repo.path, relpath(sdk_file, sdk_path))            
 | 
			
		||||
        else:
 | 
			
		||||
            repo_file = join(repo.path, sdk_file)
 | 
			
		||||
        repo_dir = dirname(repo_file)
 | 
			
		||||
        if not exists(repo_dir):
 | 
			
		||||
            print("CREATING: %s" % repo_dir)
 | 
			
		||||
            makedirs(repo_dir)
 | 
			
		||||
 | 
			
		||||
        copy_with_line_endings(sdk_file, repo_file)
 | 
			
		||||
 | 
			
		||||
    # Go through each path specified in the mbed structure 
 | 
			
		||||
    for sdk_path in sdk_paths:
 | 
			
		||||
 | 
			
		||||
        if isfile(sdk_path):
 | 
			
		||||
            # Single file so just copy directly across
 | 
			
		||||
            visit_mbed_sdk(sdk_path)
 | 
			
		||||
        else:    
 | 
			
		||||
            visit_files(sdk_path, visit_mbed_sdk)
 | 
			
		||||
 | 
			
		||||
    def sdk_remove(repo_path):
 | 
			
		||||
        
 | 
			
		||||
        print("REMOVING: %s" % repo_path)
 | 
			
		||||
        
 | 
			
		||||
        # Check if this is an empty directory or a file before determining how to 
 | 
			
		||||
        # delete it. As this function should only be called with a directory list
 | 
			
		||||
        # after being called with a file list, the directory should automatically
 | 
			
		||||
        # be either valid or empty .
 | 
			
		||||
        if isfile(repo_path):
 | 
			
		||||
            remove(repo_path)
 | 
			
		||||
        elif isdir(repo_path) and not listdir(repo_path):
 | 
			
		||||
            rmdir(repo_path)
 | 
			
		||||
        else:
 | 
			
		||||
            print("ERROR: %s is not empty, please remove manually." % repo_path)
 | 
			
		||||
            print listdir(repo_path)
 | 
			
		||||
            exit(1)
 | 
			
		||||
 | 
			
		||||
    # remove repository files that do not exist in the mbed SDK
 | 
			
		||||
    def visit_lib_repo(repo_path):
 | 
			
		||||
        for sdk_path in sdk_paths:
 | 
			
		||||
            sdk_file = join(sdk_path, relpath(repo_path, repo.path))
 | 
			
		||||
            if not exists(sdk_file):
 | 
			
		||||
                sdk_remove(repo_path)
 | 
			
		||||
 | 
			
		||||
    # remove repository files that do not exist in the mbed SDK source
 | 
			
		||||
    def visit_repo(repo_path):
 | 
			
		||||
 | 
			
		||||
        # work out equivalent sdk path from repo file
 | 
			
		||||
        sdk_path = join(getcwd(), relpath(repo_path, repo.path))
 | 
			
		||||
 | 
			
		||||
        if not exists(sdk_path):
 | 
			
		||||
            sdk_remove(repo_path)
 | 
			
		||||
 | 
			
		||||
    # Go through each path specified in the mbed structure
 | 
			
		||||
    # Check if there are any files in any of those paths that are no longer part of the SDK
 | 
			
		||||
 | 
			
		||||
    if lib:
 | 
			
		||||
        visit_files(repo.path, visit_lib_repo)
 | 
			
		||||
        # Now do the same for directories that may need to be removed. This needs to be done
 | 
			
		||||
        # bottom up to ensure any lower nested directories can be deleted first
 | 
			
		||||
        visit_dirs(repo.path, visit_lib_repo)
 | 
			
		||||
        
 | 
			
		||||
    else:
 | 
			
		||||
        visit_files(repo.path, visit_repo)
 | 
			
		||||
 | 
			
		||||
        # Now do the same for directories that may need to be removed. This needs to be done
 | 
			
		||||
        # bottom up to ensure any lower nested directories can be deleted first
 | 
			
		||||
        visit_dirs(repo.path, visit_repo)
 | 
			
		||||
    
 | 
			
		||||
    if repo.publish():
 | 
			
		||||
        changed.append(repo_name)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_code(repositories):
 | 
			
		||||
    for repo_name in repositories.keys():
 | 
			
		||||
        sdk_dirs = repositories[repo_name]
 | 
			
		||||
        print '\n=== Updating "%s" ===' % repo_name
 | 
			
		||||
        update_repo(repo_name, sdk_dirs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_mbed():
 | 
			
		||||
    update_repo("mbed", [join(BUILD_DIR, "mbed")], lib=True)
 | 
			
		||||
 | 
			
		||||
def do_sync(options):
 | 
			
		||||
    global push_remote, quiet, commit_msg, changed
 | 
			
		||||
 | 
			
		||||
    push_remote = not options.nopush
 | 
			
		||||
    quiet = options.quiet
 | 
			
		||||
    commit_msg = options.msg
 | 
			
		||||
    changed = []
 | 
			
		||||
 | 
			
		||||
    if options.code:
 | 
			
		||||
        update_code(OFFICIAL_CODE)
 | 
			
		||||
 | 
			
		||||
    if options.mbed:
 | 
			
		||||
        update_mbed()
 | 
			
		||||
 | 
			
		||||
    if changed:
 | 
			
		||||
        print "Repositories with changes:", changed
 | 
			
		||||
 | 
			
		||||
    return changed
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    parser = OptionParser()
 | 
			
		||||
 | 
			
		||||
    parser.add_option("-c", "--code",
 | 
			
		||||
                  action="store_true",  default=False,
 | 
			
		||||
                  help="Update the mbed_official code")
 | 
			
		||||
 | 
			
		||||
    parser.add_option("-m", "--mbed",
 | 
			
		||||
                  action="store_true",  default=False,
 | 
			
		||||
                  help="Release a build of the mbed library")
 | 
			
		||||
 | 
			
		||||
    parser.add_option("-n", "--nopush",
 | 
			
		||||
                  action="store_true", default=False,
 | 
			
		||||
                  help="Commit the changes locally only, don't push them")
 | 
			
		||||
 | 
			
		||||
    parser.add_option("", "--commit_message",
 | 
			
		||||
                  action="store", type="string", default='', dest='msg',
 | 
			
		||||
                  help="Commit message to use for all the commits")
 | 
			
		||||
 | 
			
		||||
    parser.add_option("-q", "--quiet",
 | 
			
		||||
                  action="store_true", default=False,
 | 
			
		||||
                  help="Don't ask for confirmation before commiting or pushing")
 | 
			
		||||
 | 
			
		||||
    (options, args) = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    do_sync(options)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,6 @@ from tools.memap import MemapParser
 | 
			
		|||
from tools.targets import TARGET_MAP, Target
 | 
			
		||||
from tools.config import Config
 | 
			
		||||
import tools.test_configs as TestConfig
 | 
			
		||||
from tools.test_db import BaseDBAccess
 | 
			
		||||
from tools.build_api import build_project, build_mbed_libs, build_lib
 | 
			
		||||
from tools.build_api import get_target_supported_toolchains
 | 
			
		||||
from tools.build_api import write_build_report
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +184,6 @@ class SingleTestRunner(object):
 | 
			
		|||
                 _clean=False,
 | 
			
		||||
                 _parser=None,
 | 
			
		||||
                 _opts=None,
 | 
			
		||||
                 _opts_db_url=None,
 | 
			
		||||
                 _opts_log_file_name=None,
 | 
			
		||||
                 _opts_report_html_file_name=None,
 | 
			
		||||
                 _opts_report_junit_file_name=None,
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +242,6 @@ class SingleTestRunner(object):
 | 
			
		|||
        self.test_spec = _test_spec
 | 
			
		||||
 | 
			
		||||
        # Settings passed e.g. from command line
 | 
			
		||||
        self.opts_db_url = _opts_db_url
 | 
			
		||||
        self.opts_log_file_name = _opts_log_file_name
 | 
			
		||||
        self.opts_report_html_file_name = _opts_report_html_file_name
 | 
			
		||||
        self.opts_report_junit_file_name = _opts_report_junit_file_name
 | 
			
		||||
| 
						 | 
				
			
			@ -284,21 +281,6 @@ class SingleTestRunner(object):
 | 
			
		|||
        # File / screen logger initialization
 | 
			
		||||
        self.logger = CLITestLogger(file_name=self.opts_log_file_name)  # Default test logger
 | 
			
		||||
 | 
			
		||||
        # Database related initializations
 | 
			
		||||
        self.db_logger = factory_db_logger(self.opts_db_url)
 | 
			
		||||
        self.db_logger_build_id = None # Build ID (database index of build_id table)
 | 
			
		||||
        # Let's connect to database to set up credentials and confirm database is ready
 | 
			
		||||
        if self.db_logger:
 | 
			
		||||
            self.db_logger.connect_url(self.opts_db_url) # Save db access info inside db_logger object
 | 
			
		||||
            if self.db_logger.is_connected():
 | 
			
		||||
                # Get hostname and uname so we can use it as build description
 | 
			
		||||
                # when creating new build_id in external database
 | 
			
		||||
                (_hostname, _uname) = self.db_logger.get_hostname()
 | 
			
		||||
                _host_location = os.path.dirname(os.path.abspath(__file__))
 | 
			
		||||
                build_id_type = None if self.opts_only_build_tests is None else self.db_logger.BUILD_ID_TYPE_BUILD_ONLY
 | 
			
		||||
                self.db_logger_build_id = self.db_logger.get_next_build_id(_hostname, desc=_uname, location=_host_location, type=build_id_type)
 | 
			
		||||
                self.db_logger.disconnect()
 | 
			
		||||
 | 
			
		||||
    def dump_options(self):
 | 
			
		||||
        """ Function returns data structure with common settings passed to SingelTestRunner
 | 
			
		||||
            It can be used for example to fill _extra fields in database storing test suite single run data
 | 
			
		||||
| 
						 | 
				
			
			@ -307,8 +289,7 @@ class SingleTestRunner(object):
 | 
			
		|||
            or
 | 
			
		||||
            data_str = json.dumps(self.dump_options())
 | 
			
		||||
        """
 | 
			
		||||
        result = {"db_url" : str(self.opts_db_url),
 | 
			
		||||
                  "log_file_name" :  str(self.opts_log_file_name),
 | 
			
		||||
        result = {"log_file_name" :  str(self.opts_log_file_name),
 | 
			
		||||
                  "shuffle_test_order" : str(self.opts_shuffle_test_order),
 | 
			
		||||
                  "shuffle_test_seed" : str(self.opts_shuffle_test_seed),
 | 
			
		||||
                  "test_by_names" :  str(self.opts_test_by_names),
 | 
			
		||||
| 
						 | 
				
			
			@ -416,27 +397,6 @@ class SingleTestRunner(object):
 | 
			
		|||
 | 
			
		||||
            if self.opts_shuffle_test_order:
 | 
			
		||||
                random.shuffle(test_map_keys, self.shuffle_random_func)
 | 
			
		||||
                # Update database with shuffle seed f applicable
 | 
			
		||||
                if self.db_logger:
 | 
			
		||||
                    self.db_logger.reconnect();
 | 
			
		||||
                    if self.db_logger.is_connected():
 | 
			
		||||
                        self.db_logger.update_build_id_info(
 | 
			
		||||
                            self.db_logger_build_id,
 | 
			
		||||
                            _shuffle_seed=self.shuffle_random_func())
 | 
			
		||||
                        self.db_logger.disconnect();
 | 
			
		||||
 | 
			
		||||
            if self.db_logger:
 | 
			
		||||
                self.db_logger.reconnect();
 | 
			
		||||
                if self.db_logger.is_connected():
 | 
			
		||||
                    # Update MUTs and Test Specification in database
 | 
			
		||||
                    self.db_logger.update_build_id_info(
 | 
			
		||||
                        self.db_logger_build_id,
 | 
			
		||||
                        _muts=self.muts, _test_spec=self.test_spec)
 | 
			
		||||
                    # Update Extra information in database (some options passed to test suite)
 | 
			
		||||
                    self.db_logger.update_build_id_info(
 | 
			
		||||
                        self.db_logger_build_id,
 | 
			
		||||
                        _extra=json.dumps(self.dump_options()))
 | 
			
		||||
                    self.db_logger.disconnect();
 | 
			
		||||
 | 
			
		||||
            valid_test_map_keys = self.get_valid_tests(test_map_keys, target, toolchain, test_ids, self.opts_include_non_automated)
 | 
			
		||||
            skipped_test_map_keys = self.get_skipped_tests(test_map_keys, valid_test_map_keys)
 | 
			
		||||
| 
						 | 
				
			
			@ -656,12 +616,6 @@ class SingleTestRunner(object):
 | 
			
		|||
                self.execute_thread_slice(q, target, toolchains, clean, test_ids, self.build_report, self.build_properties)
 | 
			
		||||
                q.get()
 | 
			
		||||
 | 
			
		||||
        if self.db_logger:
 | 
			
		||||
            self.db_logger.reconnect();
 | 
			
		||||
            if self.db_logger.is_connected():
 | 
			
		||||
                self.db_logger.update_build_id_info(self.db_logger_build_id, _status_fk=self.db_logger.BUILD_ID_STATUS_COMPLETED)
 | 
			
		||||
                self.db_logger.disconnect();
 | 
			
		||||
 | 
			
		||||
        return self.test_summary, self.shuffle_random_seed, self.test_summary_ext, self.test_suite_properties_ext, self.build_report, self.build_properties
 | 
			
		||||
 | 
			
		||||
    def get_valid_tests(self, test_map_keys, target, toolchain, test_ids, include_non_automated):
 | 
			
		||||
| 
						 | 
				
			
			@ -885,9 +839,6 @@ class SingleTestRunner(object):
 | 
			
		|||
        mcu = mut['mcu']
 | 
			
		||||
        copy_method = mut.get('copy_method')        # Available board configuration selection e.g. core selection etc.
 | 
			
		||||
 | 
			
		||||
        if self.db_logger:
 | 
			
		||||
            self.db_logger.reconnect()
 | 
			
		||||
 | 
			
		||||
        selected_copy_method = self.opts_copy_method if copy_method is None else copy_method
 | 
			
		||||
 | 
			
		||||
        # Tests can be looped so test results must be stored for the same test
 | 
			
		||||
| 
						 | 
				
			
			@ -986,27 +937,10 @@ class SingleTestRunner(object):
 | 
			
		|||
                single_test_result, target_name_unique, toolchain_name, test_id,
 | 
			
		||||
                test_description, elapsed_time, single_timeout))
 | 
			
		||||
 | 
			
		||||
            # Update database entries for ongoing test
 | 
			
		||||
            if self.db_logger and self.db_logger.is_connected():
 | 
			
		||||
                test_type = 'SingleTest'
 | 
			
		||||
                self.db_logger.insert_test_entry(self.db_logger_build_id,
 | 
			
		||||
                                                 target_name,
 | 
			
		||||
                                                 toolchain_name,
 | 
			
		||||
                                                 test_type,
 | 
			
		||||
                                                 test_id,
 | 
			
		||||
                                                 single_test_result,
 | 
			
		||||
                                                 single_test_output,
 | 
			
		||||
                                                 elapsed_time,
 | 
			
		||||
                                                 single_timeout,
 | 
			
		||||
                                                 test_index)
 | 
			
		||||
 | 
			
		||||
            # If we perform waterfall test we test until we get OK and we stop testing
 | 
			
		||||
            if self.opts_waterfall_test and single_test_result == self.TEST_RESULT_OK:
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
        if self.db_logger:
 | 
			
		||||
            self.db_logger.disconnect()
 | 
			
		||||
 | 
			
		||||
        return (self.shape_global_test_loop_result(test_all_result, self.opts_waterfall_test and self.opts_consolidate_waterfall_test),
 | 
			
		||||
                target_name_unique,
 | 
			
		||||
                toolchain_name,
 | 
			
		||||
| 
						 | 
				
			
			@ -1658,46 +1592,6 @@ class CLITestLogger(TestLogger):
 | 
			
		|||
                pass
 | 
			
		||||
        return log_line_str
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def factory_db_logger(db_url):
 | 
			
		||||
    """ Factory database driver depending on database type supplied in database connection string db_url
 | 
			
		||||
    """
 | 
			
		||||
    if db_url is not None:
 | 
			
		||||
        from tools.test_mysql import MySQLDBAccess
 | 
			
		||||
        connection_info = BaseDBAccess().parse_db_connection_string(db_url)
 | 
			
		||||
        if connection_info is not None:
 | 
			
		||||
            (db_type, username, password, host, db_name) = BaseDBAccess().parse_db_connection_string(db_url)
 | 
			
		||||
            if db_type == 'mysql':
 | 
			
		||||
                return MySQLDBAccess()
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def detect_database_verbose(db_url):
 | 
			
		||||
    """ uses verbose mode (prints) database detection sequence to check it database connection string is valid
 | 
			
		||||
    """
 | 
			
		||||
    result = BaseDBAccess().parse_db_connection_string(db_url)
 | 
			
		||||
    if result is not None:
 | 
			
		||||
        # Parsing passed
 | 
			
		||||
        (db_type, username, password, host, db_name) = result
 | 
			
		||||
        #print "DB type '%s', user name '%s', password '%s', host '%s', db name '%s'"% result
 | 
			
		||||
        # Let's try to connect
 | 
			
		||||
        db_ = factory_db_logger(db_url)
 | 
			
		||||
        if db_ is not None:
 | 
			
		||||
            print("Connecting to database '%s'..." % db_url)
 | 
			
		||||
            db_.connect(host, username, password, db_name)
 | 
			
		||||
            if db_.is_connected():
 | 
			
		||||
                print("ok")
 | 
			
		||||
                print("Detecting database...")
 | 
			
		||||
                print(db_.detect_database(verbose=True))
 | 
			
		||||
                print("Disconnecting...")
 | 
			
		||||
                db_.disconnect()
 | 
			
		||||
                print("done")
 | 
			
		||||
        else:
 | 
			
		||||
            print("Database type '%s' unknown" % db_type)
 | 
			
		||||
    else:
 | 
			
		||||
        print("Parse error: '%s' - DB Url error" % db_url)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_module_avail(module_name):
 | 
			
		||||
    """ This function returns True if module_name is already imported module
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			@ -1987,10 +1881,6 @@ def get_default_test_options_parser():
 | 
			
		|||
                        type=int,
 | 
			
		||||
                        help='You can increase global timeout for each test by specifying additional test timeout in seconds')
 | 
			
		||||
 | 
			
		||||
    parser.add_argument('--db',
 | 
			
		||||
                        dest='db_url',
 | 
			
		||||
                        help='This specifies what database test suite uses to store its state. To pass DB connection info use database connection string. Example: \'mysql://username:password@127.0.0.1/db_name\'')
 | 
			
		||||
 | 
			
		||||
    parser.add_argument('-l', '--log',
 | 
			
		||||
                        dest='log_file_name',
 | 
			
		||||
                        help='Log events to external file (note not all console entries may be visible in log file)')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										165
									
								
								tools/test_db.py
								
								
								
								
							
							
						
						
									
										165
									
								
								tools/test_db.py
								
								
								
								
							| 
						 | 
				
			
			@ -1,165 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2014 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseDBAccess():
 | 
			
		||||
    """ Class used to connect with test database and store test results
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.db_object = None
 | 
			
		||||
        self.db_type = None
 | 
			
		||||
        # Connection credentials
 | 
			
		||||
        self.host = None
 | 
			
		||||
        self.user = None
 | 
			
		||||
        self.passwd = None
 | 
			
		||||
        self.db = None
 | 
			
		||||
 | 
			
		||||
        # Test Suite DB scheme (table names)
 | 
			
		||||
        self.TABLE_BUILD_ID = 'mtest_build_id'
 | 
			
		||||
        self.TABLE_BUILD_ID_STATUS = 'mtest_build_id_status'
 | 
			
		||||
        self.TABLE_BUILD_ID_TYPE = 'mtest_build_id_type'
 | 
			
		||||
        self.TABLE_TARGET = 'mtest_target'
 | 
			
		||||
        self.TABLE_TEST_ENTRY = 'mtest_test_entry'
 | 
			
		||||
        self.TABLE_TEST_ID = 'mtest_test_id'
 | 
			
		||||
        self.TABLE_TEST_RESULT = 'mtest_test_result'
 | 
			
		||||
        self.TABLE_TEST_TYPE = 'mtest_test_type'
 | 
			
		||||
        self.TABLE_TOOLCHAIN = 'mtest_toolchain'
 | 
			
		||||
        # Build ID status PKs
 | 
			
		||||
        self.BUILD_ID_STATUS_STARTED = 1 # Started
 | 
			
		||||
        self.BUILD_ID_STATUS_IN_PROGRESS = 2 # In Progress
 | 
			
		||||
        self.BUILD_ID_STATUS_COMPLETED = 3 #Completed
 | 
			
		||||
        self.BUILD_ID_STATUS_FAILED = 4 # Failed
 | 
			
		||||
        # Build ID type PKs
 | 
			
		||||
        self.BUILD_ID_TYPE_TEST = 1 # Test
 | 
			
		||||
        self.BUILD_ID_TYPE_BUILD_ONLY = 2 # Build Only
 | 
			
		||||
 | 
			
		||||
    def get_hostname(self):
 | 
			
		||||
        """ Useful when creating build_id in database
 | 
			
		||||
            Function returns (hostname, uname) which can be used as (build_id_name, build_id_desc)
 | 
			
		||||
        """
 | 
			
		||||
        # Get hostname from socket
 | 
			
		||||
        import socket
 | 
			
		||||
        hostname = socket.gethostbyaddr(socket.gethostname())[0]
 | 
			
		||||
        # Get uname from platform resources
 | 
			
		||||
        import platform
 | 
			
		||||
        uname = json.dumps(platform.uname())
 | 
			
		||||
        return (hostname, uname)
 | 
			
		||||
 | 
			
		||||
    def get_db_type(self):
 | 
			
		||||
        """ Returns database type. E.g. 'mysql', 'sqlLite' etc.
 | 
			
		||||
        """
 | 
			
		||||
        return self.db_type
 | 
			
		||||
 | 
			
		||||
    def detect_database(self, verbose=False):
 | 
			
		||||
        """ detect database and return VERION data structure or string (verbose=True)
 | 
			
		||||
        """
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def parse_db_connection_string(self, str):
 | 
			
		||||
        """ Parsing SQL DB connection string. String should contain:
 | 
			
		||||
            - DB Name, user name, password, URL (DB host), name
 | 
			
		||||
            Function should return tuple with parsed (db_type, username, password, host, db_name) or None if error
 | 
			
		||||
 | 
			
		||||
            (db_type, username, password, host, db_name) = self.parse_db_connection_string(db_url)
 | 
			
		||||
 | 
			
		||||
            E.g. connection string: 'mysql://username:password@127.0.0.1/db_name'
 | 
			
		||||
        """
 | 
			
		||||
        result = None
 | 
			
		||||
        if type(str) == type(''):
 | 
			
		||||
            PATTERN = '^([\w]+)://([\w]+):([\w]*)@(.*)/([\w]+)'
 | 
			
		||||
            result = re.match(PATTERN, str)
 | 
			
		||||
            if result is not None:
 | 
			
		||||
                result = result.groups()    # Tuple (db_name, host, user, passwd, db)
 | 
			
		||||
        return result # (db_type, username, password, host, db_name)
 | 
			
		||||
 | 
			
		||||
    def is_connected(self):
 | 
			
		||||
        """ Returns True if we are connected to database
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def connect(self, host, user, passwd, db):
 | 
			
		||||
        """ Connects to DB and returns DB object
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def connect_url(self, db_url):
 | 
			
		||||
        """ Connects to database using db_url (database url parsing),
 | 
			
		||||
            store host, username, password, db_name
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def reconnect(self):
 | 
			
		||||
        """ Reconnects to DB and returns DB object using stored host name,
 | 
			
		||||
            database name and credentials (user name and password)
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def disconnect(self):
 | 
			
		||||
        """ Close DB connection
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def escape_string(self, str):
 | 
			
		||||
        """ Escapes string so it can be put in SQL query between quotes
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def select_all(self, query):
 | 
			
		||||
        """ Execute SELECT query and get all results
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def insert(self, query, commit=True):
 | 
			
		||||
        """ Execute INSERT query, define if you want to commit
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get_next_build_id(self, name, desc='', location='', type=None, status=None):
 | 
			
		||||
        """ Insert new build_id (DB unique build like ID number to send all test results)
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get_table_entry_pk(self, table, column, value, update_db=True):
 | 
			
		||||
        """ Checks for entries in tables with two columns (<TABLE_NAME>_pk, <column>)
 | 
			
		||||
            If update_db is True updates table entry if value in specified column doesn't exist
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def update_table_entry(self, table, column, value):
 | 
			
		||||
        """ Updates table entry if value in specified column doesn't exist
 | 
			
		||||
            Locks table to perform atomic read + update
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def update_build_id_info(self, build_id, **kw):
 | 
			
		||||
        """ Update additional data inside build_id table
 | 
			
		||||
            Examples:
 | 
			
		||||
            db.update_build_is(build_id, _status_fk=self.BUILD_ID_STATUS_COMPLETED, _shuffle_seed=0.0123456789):
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def insert_test_entry(self, build_id, target, toolchain, test_type, test_id, test_result, test_time, test_timeout, test_loop, test_extra=''):
 | 
			
		||||
        """ Inserts test result entry to database. All checks regarding existing
 | 
			
		||||
            toolchain names in DB are performed.
 | 
			
		||||
            If some data is missing DB will be updated
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
| 
						 | 
				
			
			@ -1,271 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2014 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
import MySQLdb as mdb
 | 
			
		||||
 | 
			
		||||
# Imports from TEST API
 | 
			
		||||
from tools.test_db import BaseDBAccess
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MySQLDBAccess(BaseDBAccess):
 | 
			
		||||
    """ Wrapper for MySQL DB access for common test suite interface
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        BaseDBAccess.__init__(self)
 | 
			
		||||
        self.DB_TYPE = 'mysql'
 | 
			
		||||
 | 
			
		||||
    def detect_database(self, verbose=False):
 | 
			
		||||
        """ detect database and return VERION data structure or string (verbose=True)
 | 
			
		||||
        """
 | 
			
		||||
        query = 'SHOW VARIABLES LIKE "%version%"'
 | 
			
		||||
        rows = self.select_all(query)
 | 
			
		||||
        if verbose:
 | 
			
		||||
            result = []
 | 
			
		||||
            for row in rows:
 | 
			
		||||
                result.append("\t%s: %s"% (row['Variable_name'], row['Value']))
 | 
			
		||||
            result = "\n".join(result)
 | 
			
		||||
        else:
 | 
			
		||||
            result = rows
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def parse_db_connection_string(self, str):
 | 
			
		||||
        """ Parsing SQL DB connection string. String should contain:
 | 
			
		||||
            - DB Name, user name, password, URL (DB host), name
 | 
			
		||||
            Function should return tuple with parsed (host, user, passwd, db) or None if error
 | 
			
		||||
            E.g. connection string: 'mysql://username:password@127.0.0.1/db_name'
 | 
			
		||||
        """
 | 
			
		||||
        result = BaseDBAccess().parse_db_connection_string(str)
 | 
			
		||||
        if result is not None:
 | 
			
		||||
            (db_type, username, password, host, db_name) = result
 | 
			
		||||
            if db_type != 'mysql':
 | 
			
		||||
                result = None
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def is_connected(self):
 | 
			
		||||
        """ Returns True if we are connected to database
 | 
			
		||||
        """
 | 
			
		||||
        return self.db_object is not None
 | 
			
		||||
 | 
			
		||||
    def connect(self, host, user, passwd, db):
 | 
			
		||||
        """ Connects to DB and returns DB object
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            self.db_object = mdb.connect(host=host, user=user, passwd=passwd, db=db)
 | 
			
		||||
            # Let's remember connection credentials
 | 
			
		||||
            self.db_type = self.DB_TYPE
 | 
			
		||||
            self.host = host
 | 
			
		||||
            self.user = user
 | 
			
		||||
            self.passwd = passwd
 | 
			
		||||
            self.db = db
 | 
			
		||||
        except mdb.Error, e:
 | 
			
		||||
            print "Error %d: %s"% (e.args[0], e.args[1])
 | 
			
		||||
            self.db_object = None
 | 
			
		||||
            self.db_type = None
 | 
			
		||||
            self.host = None
 | 
			
		||||
            self.user = None
 | 
			
		||||
            self.passwd = None
 | 
			
		||||
            self.db = None
 | 
			
		||||
 | 
			
		||||
    def connect_url(self, db_url):
 | 
			
		||||
        """ Connects to database using db_url (database url parsing),
 | 
			
		||||
            store host, username, password, db_name
 | 
			
		||||
        """
 | 
			
		||||
        result = self.parse_db_connection_string(db_url)
 | 
			
		||||
        if result is not None:
 | 
			
		||||
            (db_type, username, password, host, db_name) = result
 | 
			
		||||
            if db_type == self.DB_TYPE:
 | 
			
		||||
                self.connect(host, username, password, db_name)
 | 
			
		||||
 | 
			
		||||
    def reconnect(self):
 | 
			
		||||
        """ Reconnects to DB and returns DB object using stored host name,
 | 
			
		||||
            database name and credentials (user name and password)
 | 
			
		||||
        """
 | 
			
		||||
        self.connect(self.host, self.user, self.passwd, self.db)
 | 
			
		||||
 | 
			
		||||
    def disconnect(self):
 | 
			
		||||
        """ Close DB connection
 | 
			
		||||
        """
 | 
			
		||||
        if self.db_object:
 | 
			
		||||
            self.db_object.close()
 | 
			
		||||
        self.db_object = None
 | 
			
		||||
        self.db_type = None
 | 
			
		||||
 | 
			
		||||
    def escape_string(self, str):
 | 
			
		||||
        """ Escapes string so it can be put in SQL query between quotes
 | 
			
		||||
        """
 | 
			
		||||
        con = self.db_object
 | 
			
		||||
        result = con.escape_string(str)
 | 
			
		||||
        return result if result else ''
 | 
			
		||||
 | 
			
		||||
    def select_all(self, query):
 | 
			
		||||
        """ Execute SELECT query and get all results
 | 
			
		||||
        """
 | 
			
		||||
        con = self.db_object
 | 
			
		||||
        cur = con.cursor(mdb.cursors.DictCursor)
 | 
			
		||||
        cur.execute(query)
 | 
			
		||||
        rows = cur.fetchall()
 | 
			
		||||
        return rows
 | 
			
		||||
 | 
			
		||||
    def insert(self, query, commit=True):
 | 
			
		||||
        """ Execute INSERT query, define if you want to commit
 | 
			
		||||
        """
 | 
			
		||||
        con = self.db_object
 | 
			
		||||
        cur = con.cursor()
 | 
			
		||||
        cur.execute(query)
 | 
			
		||||
        if commit:
 | 
			
		||||
            con.commit()
 | 
			
		||||
        return cur.lastrowid
 | 
			
		||||
 | 
			
		||||
    def get_next_build_id(self, name, desc='', location='', type=None, status=None):
 | 
			
		||||
        """ Insert new build_id (DB unique build like ID number to send all test results)
 | 
			
		||||
        """
 | 
			
		||||
        if status is None:
 | 
			
		||||
            status = self.BUILD_ID_STATUS_STARTED
 | 
			
		||||
 | 
			
		||||
        if type is None:
 | 
			
		||||
            type = self.BUILD_ID_TYPE_TEST
 | 
			
		||||
 | 
			
		||||
        query = """INSERT INTO `%s` (%s_name, %s_desc, %s_location, %s_type_fk, %s_status_fk)
 | 
			
		||||
                        VALUES ('%s', '%s', '%s', %d, %d)"""% (self.TABLE_BUILD_ID,
 | 
			
		||||
                                                               self.TABLE_BUILD_ID,
 | 
			
		||||
                                                               self.TABLE_BUILD_ID,
 | 
			
		||||
                                                               self.TABLE_BUILD_ID,
 | 
			
		||||
                                                               self.TABLE_BUILD_ID,
 | 
			
		||||
                                                               self.TABLE_BUILD_ID,
 | 
			
		||||
                                                               self.escape_string(name),
 | 
			
		||||
                                                               self.escape_string(desc),
 | 
			
		||||
                                                               self.escape_string(location),
 | 
			
		||||
                                                               type,
 | 
			
		||||
                                                               status)
 | 
			
		||||
        index = self.insert(query) # Provide inserted record PK
 | 
			
		||||
        return index
 | 
			
		||||
 | 
			
		||||
    def get_table_entry_pk(self, table, column, value, update_db=True):
 | 
			
		||||
        """ Checks for entries in tables with two columns (<TABLE_NAME>_pk, <column>)
 | 
			
		||||
            If update_db is True updates table entry if value in specified column doesn't exist
 | 
			
		||||
        """
 | 
			
		||||
        # TODO: table buffering
 | 
			
		||||
        result = None
 | 
			
		||||
        table_pk = '%s_pk'% table
 | 
			
		||||
        query = """SELECT `%s`
 | 
			
		||||
                     FROM `%s`
 | 
			
		||||
                    WHERE `%s`='%s'"""% (table_pk,
 | 
			
		||||
                                         table,
 | 
			
		||||
                                         column,
 | 
			
		||||
                                         self.escape_string(value))
 | 
			
		||||
        rows = self.select_all(query)
 | 
			
		||||
        if len(rows) == 1:
 | 
			
		||||
            result = rows[0][table_pk]
 | 
			
		||||
        elif len(rows) == 0 and update_db:
 | 
			
		||||
            # Update DB with new value
 | 
			
		||||
            result = self.update_table_entry(table, column, value)
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def update_table_entry(self, table, column, value):
 | 
			
		||||
        """ Updates table entry if value in specified column doesn't exist
 | 
			
		||||
            Locks table to perform atomic read + update
 | 
			
		||||
        """
 | 
			
		||||
        result = None
 | 
			
		||||
        con = self.db_object
 | 
			
		||||
        cur = con.cursor()
 | 
			
		||||
        cur.execute("LOCK TABLES `%s` WRITE"% table)
 | 
			
		||||
        table_pk = '%s_pk'% table
 | 
			
		||||
        query = """SELECT `%s`
 | 
			
		||||
                     FROM `%s`
 | 
			
		||||
                    WHERE `%s`='%s'"""% (table_pk,
 | 
			
		||||
                                         table,
 | 
			
		||||
                                         column,
 | 
			
		||||
                                         self.escape_string(value))
 | 
			
		||||
        cur.execute(query)
 | 
			
		||||
        rows = cur.fetchall()
 | 
			
		||||
        if len(rows) == 0:
 | 
			
		||||
            query = """INSERT INTO `%s` (%s)
 | 
			
		||||
                            VALUES ('%s')"""% (table,
 | 
			
		||||
                                               column,
 | 
			
		||||
                                               self.escape_string(value))
 | 
			
		||||
            cur.execute(query)
 | 
			
		||||
            result = cur.lastrowid
 | 
			
		||||
        con.commit()
 | 
			
		||||
        cur.execute("UNLOCK TABLES")
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def update_build_id_info(self, build_id, **kw):
 | 
			
		||||
        """ Update additional data inside build_id table
 | 
			
		||||
            Examples:
 | 
			
		||||
            db.update_build_id_info(build_id, _status_fk=self.BUILD_ID_STATUS_COMPLETED, _shuffle_seed=0.0123456789):
 | 
			
		||||
        """
 | 
			
		||||
        if len(kw):
 | 
			
		||||
            con = self.db_object
 | 
			
		||||
            cur = con.cursor()
 | 
			
		||||
            # Prepare UPDATE query
 | 
			
		||||
            # ["`mtest_build_id_pk`=[value-1]", "`mtest_build_id_name`=[value-2]", "`mtest_build_id_desc`=[value-3]"]
 | 
			
		||||
            set_list = []
 | 
			
		||||
            for col_sufix in kw:
 | 
			
		||||
                assign_str = "`%s%s`='%s'"% (self.TABLE_BUILD_ID, col_sufix, self.escape_string(str(kw[col_sufix])))
 | 
			
		||||
                set_list.append(assign_str)
 | 
			
		||||
            set_str = ', '.join(set_list)
 | 
			
		||||
            query = """UPDATE `%s`
 | 
			
		||||
                          SET %s
 | 
			
		||||
                        WHERE `mtest_build_id_pk`=%d"""% (self.TABLE_BUILD_ID,
 | 
			
		||||
                                                          set_str,
 | 
			
		||||
                                                          build_id)
 | 
			
		||||
            cur.execute(query)
 | 
			
		||||
            con.commit()
 | 
			
		||||
 | 
			
		||||
    def insert_test_entry(self, build_id, target, toolchain, test_type, test_id, test_result, test_output, test_time, test_timeout, test_loop, test_extra=''):
 | 
			
		||||
        """ Inserts test result entry to database. All checks regarding existing
 | 
			
		||||
            toolchain names in DB are performed.
 | 
			
		||||
            If some data is missing DB will be updated
 | 
			
		||||
        """
 | 
			
		||||
        # Get all table FK and if entry is new try to insert new value
 | 
			
		||||
        target_fk = self.get_table_entry_pk(self.TABLE_TARGET, self.TABLE_TARGET + '_name', target)
 | 
			
		||||
        toolchain_fk = self.get_table_entry_pk(self.TABLE_TOOLCHAIN, self.TABLE_TOOLCHAIN + '_name', toolchain)
 | 
			
		||||
        test_type_fk = self.get_table_entry_pk(self.TABLE_TEST_TYPE, self.TABLE_TEST_TYPE + '_name', test_type)
 | 
			
		||||
        test_id_fk = self.get_table_entry_pk(self.TABLE_TEST_ID, self.TABLE_TEST_ID + '_name', test_id)
 | 
			
		||||
        test_result_fk = self.get_table_entry_pk(self.TABLE_TEST_RESULT, self.TABLE_TEST_RESULT + '_name', test_result)
 | 
			
		||||
 | 
			
		||||
        con = self.db_object
 | 
			
		||||
        cur = con.cursor()
 | 
			
		||||
 | 
			
		||||
        query = """ INSERT INTO `%s` (`mtest_build_id_fk`,
 | 
			
		||||
                                      `mtest_target_fk`,
 | 
			
		||||
                                      `mtest_toolchain_fk`,
 | 
			
		||||
                                      `mtest_test_type_fk`,
 | 
			
		||||
                                      `mtest_test_id_fk`,
 | 
			
		||||
                                      `mtest_test_result_fk`,
 | 
			
		||||
                                      `mtest_test_output`,
 | 
			
		||||
                                      `mtest_test_time`,
 | 
			
		||||
                                      `mtest_test_timeout`,
 | 
			
		||||
                                      `mtest_test_loop_no`,
 | 
			
		||||
                                      `mtest_test_result_extra`)
 | 
			
		||||
                         VALUES (%d, %d, %d, %d, %d, %d, '%s', %.2f, %.2f, %d, '%s')"""% (self.TABLE_TEST_ENTRY,
 | 
			
		||||
                                                                                          build_id,
 | 
			
		||||
                                                                                          target_fk,
 | 
			
		||||
                                                                                          toolchain_fk,
 | 
			
		||||
                                                                                          test_type_fk,
 | 
			
		||||
                                                                                          test_id_fk,
 | 
			
		||||
                                                                                          test_result_fk,
 | 
			
		||||
                                                                                          self.escape_string(test_output),
 | 
			
		||||
                                                                                          test_time,
 | 
			
		||||
                                                                                          test_timeout,
 | 
			
		||||
                                                                                          test_loop,
 | 
			
		||||
                                                                                          self.escape_string(test_extra))
 | 
			
		||||
        cur.execute(query)
 | 
			
		||||
        con.commit()
 | 
			
		||||
| 
						 | 
				
			
			@ -1,243 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2014 ARM Limited
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
Author: Przemyslaw Wirkus <Przemyslaw.wirkus@arm.com>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import json
 | 
			
		||||
import optparse
 | 
			
		||||
from flask import Flask
 | 
			
		||||
from os.path import join, abspath, dirname
 | 
			
		||||
 | 
			
		||||
# Be sure that the tools directory is in the search path
 | 
			
		||||
ROOT = abspath(join(dirname(__file__), ".."))
 | 
			
		||||
sys.path.insert(0, ROOT)
 | 
			
		||||
 | 
			
		||||
# Imports related to mbed build api
 | 
			
		||||
from tools.utils import construct_enum
 | 
			
		||||
from tools.build_api import mcu_toolchain_matrix
 | 
			
		||||
 | 
			
		||||
# Imports from TEST API
 | 
			
		||||
from test_api import SingleTestRunner
 | 
			
		||||
from test_api import SingleTestExecutor
 | 
			
		||||
from test_api import get_json_data_from_file
 | 
			
		||||
from test_api import print_muts_configuration_from_json
 | 
			
		||||
from test_api import print_test_configuration_from_json
 | 
			
		||||
from test_api import get_avail_tests_summary_table
 | 
			
		||||
from test_api import get_default_test_options_parser
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SingleTestRunnerWebService(SingleTestRunner):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super(SingleTestRunnerWebService, self).__init__()
 | 
			
		||||
 | 
			
		||||
        # With this lock we should control access to certain resources inside this class
 | 
			
		||||
        self.resource_lock = thread.allocate_lock()
 | 
			
		||||
 | 
			
		||||
        self.RestRequest = construct_enum(REST_MUTS='muts',
 | 
			
		||||
                                          REST_TEST_SPEC='test_spec',
 | 
			
		||||
                                          REST_TEST_RESULTS='test_results')
 | 
			
		||||
 | 
			
		||||
    def get_rest_result_template(self, result, command, success_code):
 | 
			
		||||
        """ Returns common part of every web service request
 | 
			
		||||
        """
 | 
			
		||||
        result = {"result" : result,
 | 
			
		||||
                  "command" : command,
 | 
			
		||||
                  "success_code": success_code} # 0 - OK, >0 - Error number
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    # REST API handlers for Flask framework
 | 
			
		||||
    def rest_api_status(self):
 | 
			
		||||
        """ Returns current test execution status. E.g. running / finished etc.
 | 
			
		||||
        """
 | 
			
		||||
        with self.resource_lock:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
    def rest_api_config(self):
 | 
			
		||||
        """ Returns configuration passed to SingleTest executor
 | 
			
		||||
        """
 | 
			
		||||
        with self.resource_lock:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
    def rest_api_log(self):
 | 
			
		||||
        """ Returns current test log """
 | 
			
		||||
        with self.resource_lock:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
    def rest_api_request_handler(self, request_type):
 | 
			
		||||
        """ Returns various data structures. Both static and mutable during test
 | 
			
		||||
        """
 | 
			
		||||
        result = {}
 | 
			
		||||
        success_code = 0
 | 
			
		||||
        with self.resource_lock:
 | 
			
		||||
            if request_type == self.RestRequest.REST_MUTS:
 | 
			
		||||
                result = self.muts # Returns MUTs
 | 
			
		||||
            elif request_type == self.RestRequest.REST_TEST_SPEC:
 | 
			
		||||
                result = self.test_spec # Returns Test Specification
 | 
			
		||||
            elif request_type == self.RestRequest.REST_TEST_RESULTS:
 | 
			
		||||
                pass # Returns test results
 | 
			
		||||
            else:
 | 
			
		||||
                success_code = -1
 | 
			
		||||
        return json.dumps(self.get_rest_result_template(result, 'request/' + request_type, success_code), indent=4)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def singletest_in_webservice_mode():
 | 
			
		||||
    # TODO Implement this web service functionality
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_default_test_webservice_options_parser():
 | 
			
		||||
    """ Get test script web service options used by CLI, webservices etc.
 | 
			
		||||
    """
 | 
			
		||||
    parser = get_default_test_options_parser()
 | 
			
		||||
 | 
			
		||||
    # Things related to web services offered by test suite scripts
 | 
			
		||||
    parser.add_argument('', '--rest-api',
 | 
			
		||||
                        dest='rest_api_enabled',
 | 
			
		||||
                        default=False,
 | 
			
		||||
                        action="store_true",
 | 
			
		||||
                        help='Enables REST API.')
 | 
			
		||||
 | 
			
		||||
    parser.add_argument('', '--rest-api-port',
 | 
			
		||||
                        dest='rest_api_port_no',
 | 
			
		||||
                        type=int,
 | 
			
		||||
                        help='Sets port for REST API interface')
 | 
			
		||||
 | 
			
		||||
    return parser
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    # Command line options
 | 
			
		||||
    parser = get_default_test_options_parser()
 | 
			
		||||
 | 
			
		||||
    parser.description = """This script allows you to run mbed defined test cases for particular MCU(s) and corresponding toolchain(s)."""
 | 
			
		||||
    parser.epilog = """Example: singletest.py -i test_spec.json -M muts_all.json"""
 | 
			
		||||
 | 
			
		||||
    (opts, args) = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    # Print summary / information about automation test status
 | 
			
		||||
    if opts.test_automation_report:
 | 
			
		||||
        print get_avail_tests_summary_table()
 | 
			
		||||
        exit(0)
 | 
			
		||||
 | 
			
		||||
    # Print summary / information about automation test status
 | 
			
		||||
    if opts.test_case_report:
 | 
			
		||||
        test_case_report_cols = ['id', 'automated', 'description', 'peripherals', 'host_test', 'duration', 'source_dir']
 | 
			
		||||
        print get_avail_tests_summary_table(cols=test_case_report_cols, result_summary=False, join_delim='\n')
 | 
			
		||||
        exit(0)
 | 
			
		||||
 | 
			
		||||
    # Only prints matrix of supported toolchains
 | 
			
		||||
    if opts.supported_toolchains:
 | 
			
		||||
        print mcu_toolchain_matrix(platform_filter=opts.general_filter_regex)
 | 
			
		||||
        exit(0)
 | 
			
		||||
 | 
			
		||||
    # Open file with test specification
 | 
			
		||||
    # test_spec_filename tells script which targets and their toolchain(s)
 | 
			
		||||
    # should be covered by the test scenario
 | 
			
		||||
    test_spec = get_json_data_from_file(opts.test_spec_filename) if opts.test_spec_filename else None
 | 
			
		||||
    if test_spec is None:
 | 
			
		||||
        if not opts.test_spec_filename:
 | 
			
		||||
            parser.print_help()
 | 
			
		||||
        exit(-1)
 | 
			
		||||
 | 
			
		||||
    # Get extra MUTs if applicable
 | 
			
		||||
    MUTs = get_json_data_from_file(opts.muts_spec_filename) if opts.muts_spec_filename else None
 | 
			
		||||
 | 
			
		||||
    if MUTs is None:
 | 
			
		||||
        if not opts.muts_spec_filename:
 | 
			
		||||
            parser.print_help()
 | 
			
		||||
        exit(-1)
 | 
			
		||||
 | 
			
		||||
    # Only prints read MUTs configuration
 | 
			
		||||
    if MUTs and opts.verbose_test_configuration_only:
 | 
			
		||||
        print "MUTs configuration in %s:"% opts.muts_spec_filename
 | 
			
		||||
        print print_muts_configuration_from_json(MUTs)
 | 
			
		||||
        print
 | 
			
		||||
        print "Test specification in %s:"% opts.test_spec_filename
 | 
			
		||||
        print print_test_configuration_from_json(test_spec)
 | 
			
		||||
        exit(0)
 | 
			
		||||
 | 
			
		||||
    # Verbose test specification and MUTs configuration
 | 
			
		||||
    if MUTs and opts.verbose:
 | 
			
		||||
        print print_muts_configuration_from_json(MUTs)
 | 
			
		||||
    if test_spec and opts.verbose:
 | 
			
		||||
        print print_test_configuration_from_json(test_spec)
 | 
			
		||||
 | 
			
		||||
    if opts.only_build_tests:
 | 
			
		||||
        # We are skipping testing phase, and suppress summary
 | 
			
		||||
        opts.suppress_summary = True
 | 
			
		||||
 | 
			
		||||
    single_test = SingleTestRunner(_global_loops_count=opts.test_global_loops_value,
 | 
			
		||||
                                   _test_loops_list=opts.test_loops_list,
 | 
			
		||||
                                   _muts=MUTs,
 | 
			
		||||
                                   _test_spec=test_spec,
 | 
			
		||||
                                   _opts_goanna_for_mbed_sdk=opts.goanna_for_mbed_sdk,
 | 
			
		||||
                                   _opts_goanna_for_tests=opts.goanna_for_tests,
 | 
			
		||||
                                   _opts_shuffle_test_order=opts.shuffle_test_order,
 | 
			
		||||
                                   _opts_shuffle_test_seed=opts.shuffle_test_seed,
 | 
			
		||||
                                   _opts_test_by_names=opts.test_by_names,
 | 
			
		||||
                                   _opts_test_only_peripheral=opts.test_only_peripheral,
 | 
			
		||||
                                   _opts_test_only_common=opts.test_only_common,
 | 
			
		||||
                                   _opts_verbose_skipped_tests=opts.verbose_skipped_tests,
 | 
			
		||||
                                   _opts_verbose_test_result_only=opts.verbose_test_result_only,
 | 
			
		||||
                                   _opts_verbose=opts.verbose,
 | 
			
		||||
                                   _opts_firmware_global_name=opts.firmware_global_name,
 | 
			
		||||
                                   _opts_only_build_tests=opts.only_build_tests,
 | 
			
		||||
                                   _opts_suppress_summary=opts.suppress_summary,
 | 
			
		||||
                                   _opts_test_x_toolchain_summary=opts.test_x_toolchain_summary,
 | 
			
		||||
                                   _opts_copy_method=opts.copy_method
 | 
			
		||||
                                   )
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        st_exec_thread = SingleTestExecutor(single_test)
 | 
			
		||||
    except KeyboardInterrupt, e:
 | 
			
		||||
        print "\n[CTRL+c] exit"
 | 
			
		||||
    st_exec_thread.start()
 | 
			
		||||
 | 
			
		||||
    if opts.rest_api_enabled:
 | 
			
		||||
        # Enable REST API
 | 
			
		||||
 | 
			
		||||
        app = Flask(__name__)
 | 
			
		||||
 | 
			
		||||
        @app.route('/')
 | 
			
		||||
        def hello_world():
 | 
			
		||||
            return 'Hello World!'
 | 
			
		||||
 | 
			
		||||
        @app.route('/status')
 | 
			
		||||
        def rest_api_status():
 | 
			
		||||
            return single_test.rest_api_status() # TODO
 | 
			
		||||
 | 
			
		||||
        @app.route('/config')
 | 
			
		||||
        def rest_api_config():
 | 
			
		||||
            return single_test.rest_api_config() # TODO
 | 
			
		||||
 | 
			
		||||
        @app.route('/log')
 | 
			
		||||
        def rest_api_log():
 | 
			
		||||
            return single_test.rest_api_log() # TODO
 | 
			
		||||
 | 
			
		||||
        @app.route('/request/<request_type>') # 'muts', 'test_spec', 'test_results'
 | 
			
		||||
        def rest_api_request_handler(request_type):
 | 
			
		||||
            result = single_test.rest_api_request_handler(request_type) # TODO
 | 
			
		||||
            return result
 | 
			
		||||
 | 
			
		||||
        rest_api_port = int(opts.rest_api_port_no) if opts.rest_api_port_no else 5555
 | 
			
		||||
        app.debug = False
 | 
			
		||||
        app.run(port=rest_api_port) # Blocking Flask REST API web service
 | 
			
		||||
    else:
 | 
			
		||||
        st_exec_thread.join()
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
| 
						 | 
				
			
			@ -15,9 +15,21 @@ See the License for the specific language governing permissions and
 | 
			
		|||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
from tools.paths import *
 | 
			
		||||
from tools.data.support import DEFAULT_SUPPORT, CORTEX_ARM_SUPPORT
 | 
			
		||||
from argparse import ArgumentTypeError
 | 
			
		||||
from tools.utils import columnate
 | 
			
		||||
from tools.targets import TARGETS
 | 
			
		||||
 | 
			
		||||
DEFAULT_SUPPORT = {}
 | 
			
		||||
CORTEX_ARM_SUPPORT = {}
 | 
			
		||||
 | 
			
		||||
for target in TARGETS:
 | 
			
		||||
    DEFAULT_SUPPORT[target.name] = target.supported_toolchains
 | 
			
		||||
 | 
			
		||||
    if target.core.startswith('Cortex'):
 | 
			
		||||
        CORTEX_ARM_SUPPORT[target.name] = [
 | 
			
		||||
            t for t in target.supported_toolchains
 | 
			
		||||
            if (t == 'ARM' or t == 'uARM')
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
TEST_CMSIS_LIB = join(TEST_DIR, "cmsis", "lib")
 | 
			
		||||
TEST_MBED_LIB = join(TEST_DIR, "mbed", "env")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,373 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2011-2013 ARM Limited
 | 
			
		||||
 | 
			
		||||
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 sys
 | 
			
		||||
import argparse
 | 
			
		||||
import xml.etree.ElementTree as ET
 | 
			
		||||
import requests
 | 
			
		||||
import urlparse
 | 
			
		||||
 | 
			
		||||
def create_headers(args):
 | 
			
		||||
    return { 'X-Api-Key':  args.api_key }
 | 
			
		||||
 | 
			
		||||
def finish_command(command, response):
 | 
			
		||||
    print(command, response.status_code, response.reason)
 | 
			
		||||
    print(response.text)
 | 
			
		||||
 | 
			
		||||
    if response.status_code < 400:
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
    else:
 | 
			
		||||
        sys.exit(2)
 | 
			
		||||
 | 
			
		||||
def create_build(args):
 | 
			
		||||
    build = {}
 | 
			
		||||
    build['buildType'] = args.build_type
 | 
			
		||||
    build['number'] = args.build_number
 | 
			
		||||
    build['source'] = args.build_source
 | 
			
		||||
    build['status'] = 'running'
 | 
			
		||||
 | 
			
		||||
    r = requests.post(urlparse.urljoin(args.url, "api/builds"), headers=create_headers(args), json=build)
 | 
			
		||||
 | 
			
		||||
    if r.status_code < 400:
 | 
			
		||||
        if args.property_file_format:
 | 
			
		||||
            print("MBED_BUILD_ID=" + r.text)
 | 
			
		||||
        else:
 | 
			
		||||
            print(r.text)
 | 
			
		||||
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
    else:
 | 
			
		||||
        sys.exit(2)
 | 
			
		||||
 | 
			
		||||
def finish_build(args):
 | 
			
		||||
    data = {}
 | 
			
		||||
    data['status'] = 'completed'
 | 
			
		||||
 | 
			
		||||
    r = requests.put(urlparse.urljoin(args.url, "api/builds/" + args.build_id), headers=create_headers(args), json=data)
 | 
			
		||||
    finish_command('finish-build', r)
 | 
			
		||||
 | 
			
		||||
def promote_build(args):
 | 
			
		||||
    data = {}
 | 
			
		||||
    data['buildType'] = 'Release'
 | 
			
		||||
 | 
			
		||||
    r = requests.put(urlparse.urljoin(args.url, "api/builds/" + args.build_id), headers=create_headers(args), json=data)
 | 
			
		||||
    finish_command('promote-build', r)
 | 
			
		||||
 | 
			
		||||
def abort_build(args):
 | 
			
		||||
    data = {}
 | 
			
		||||
    data['status'] = 'aborted'
 | 
			
		||||
 | 
			
		||||
    r = requests.put(urlparse.urljoin(args.url, "api/builds/" + args.build_id), headers=create_headers(args), json=data)
 | 
			
		||||
    finish_command('abort-build', r)
 | 
			
		||||
 | 
			
		||||
def add_project_runs(args):
 | 
			
		||||
    '''
 | 
			
		||||
    -------------------------------------
 | 
			
		||||
    Notes on 'project_run_data' structure:
 | 
			
		||||
    --------------------------------------
 | 
			
		||||
        'projectRuns' - Tree structure used to keep track of what projects have
 | 
			
		||||
            been logged in different report files. The tree is organized as follows:
 | 
			
		||||
 | 
			
		||||
            'projectRuns': {                - Root element of tree
 | 
			
		||||
 | 
			
		||||
                'hostOs': {                 - Host OS on which project was built/tested
 | 
			
		||||
                                                - ex. windows, linux, or mac
 | 
			
		||||
 | 
			
		||||
                    'platform': {           - Platform for which project was built/tested
 | 
			
		||||
                                              (Corresponds to platform names in targets.py)
 | 
			
		||||
                                                - ex. K64F, LPC1768, NRF51822, etc.
 | 
			
		||||
 | 
			
		||||
                        'toolchain': {      - Toolchain with which project was built/tested
 | 
			
		||||
                                              (Corresponds to TOOLCHAIN_CLASSES names in toolchains/__init__.py)
 | 
			
		||||
                                                - ex. ARM, uARM, GCC_ARM, etc.
 | 
			
		||||
 | 
			
		||||
                            'project': {    - Project that was build/tested
 | 
			
		||||
                                              (Corresponds to test id in tests.py or library id in libraries.py)
 | 
			
		||||
                                                - For tests, ex. MBED_A1, MBED_11, DTCT_1 etc.
 | 
			
		||||
                                                - For libraries, ex. MBED, RTX, RTOS, etc.
 | 
			
		||||
 | 
			
		||||
                            },
 | 
			
		||||
                            ...
 | 
			
		||||
                        },
 | 
			
		||||
                        ...
 | 
			
		||||
                    },
 | 
			
		||||
                    ...
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        'platforms_set' - Set of all the platform names mentioned in the given report files
 | 
			
		||||
 | 
			
		||||
        'toolchains_set' - Set of all the toolchain names mentioned in the given report files
 | 
			
		||||
 | 
			
		||||
        'names_set' - Set of all the project names mentioned in the given report files
 | 
			
		||||
 | 
			
		||||
        'hostOses_set' - Set of all the host names given (only given by the command line arguments)
 | 
			
		||||
    '''
 | 
			
		||||
 | 
			
		||||
    project_run_data = {}
 | 
			
		||||
    project_run_data['projectRuns'] = {}
 | 
			
		||||
    project_run_data['platforms_set'] = set()
 | 
			
		||||
    project_run_data['vendors_set'] = set()
 | 
			
		||||
    project_run_data['toolchains_set'] = set()
 | 
			
		||||
    project_run_data['names_set'] = set()
 | 
			
		||||
    project_run_data['hostOses_set'] = set()
 | 
			
		||||
    project_run_data['hostOses_set'].add(args.host_os)
 | 
			
		||||
 | 
			
		||||
    if args.build_report:
 | 
			
		||||
        add_report(project_run_data, args.build_report, True, args.build_id, args.host_os)
 | 
			
		||||
 | 
			
		||||
    if args.test_report:
 | 
			
		||||
        add_report(project_run_data, args.test_report, False, args.build_id, args.host_os)
 | 
			
		||||
 | 
			
		||||
    ts_data = format_project_run_data(project_run_data, args.limit)
 | 
			
		||||
    total_result = True
 | 
			
		||||
    
 | 
			
		||||
    total_parts = len(ts_data)
 | 
			
		||||
    print "Uploading project runs in %d parts" % total_parts
 | 
			
		||||
    
 | 
			
		||||
    for index, data in enumerate(ts_data):
 | 
			
		||||
        r = requests.post(urlparse.urljoin(args.url, "api/projectRuns"), headers=create_headers(args), json=data)
 | 
			
		||||
        print("add-project-runs part %d/%d" % (index + 1, total_parts), r.status_code, r.reason)
 | 
			
		||||
        print(r.text)
 | 
			
		||||
    
 | 
			
		||||
        if r.status_code >= 400:
 | 
			
		||||
            total_result = False
 | 
			
		||||
    
 | 
			
		||||
    if total_result:
 | 
			
		||||
        print "'add-project-runs' completed successfully"
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
    else:
 | 
			
		||||
        print "'add-project-runs' failed"
 | 
			
		||||
        sys.exit(2)
 | 
			
		||||
 | 
			
		||||
def prep_ts_data():
 | 
			
		||||
    ts_data = {}
 | 
			
		||||
    ts_data['projectRuns'] = []
 | 
			
		||||
    ts_data['platforms'] = set()
 | 
			
		||||
    ts_data['vendors'] = set()
 | 
			
		||||
    ts_data['toolchains'] = set()
 | 
			
		||||
    ts_data['names'] = set()
 | 
			
		||||
    ts_data['hostOses'] = set()
 | 
			
		||||
    return ts_data
 | 
			
		||||
 | 
			
		||||
def finish_ts_data(ts_data, project_run_data):
 | 
			
		||||
    ts_data['platforms'] = list(ts_data['platforms'])
 | 
			
		||||
    ts_data['vendors'] = list(ts_data['vendors'])
 | 
			
		||||
    ts_data['toolchains'] = list(ts_data['toolchains'])
 | 
			
		||||
    ts_data['names'] = list(ts_data['names'])
 | 
			
		||||
    ts_data['hostOses'] = list(ts_data['hostOses'])
 | 
			
		||||
    
 | 
			
		||||
    # Add all vendors to every projectRun submission
 | 
			
		||||
    # TODO Either add "vendor" to the "project_run_data"
 | 
			
		||||
    #      or remove "vendor" entirely from the viewer
 | 
			
		||||
    ts_data['vendors'] = list(project_run_data['vendors_set'])
 | 
			
		||||
    
 | 
			
		||||
def format_project_run_data(project_run_data, limit):
 | 
			
		||||
    all_ts_data = []
 | 
			
		||||
    current_limit_count = 0
 | 
			
		||||
    
 | 
			
		||||
    ts_data = prep_ts_data()
 | 
			
		||||
    ts_data['projectRuns'] = []
 | 
			
		||||
 | 
			
		||||
    for hostOs_name, hostOs in project_run_data['projectRuns'].items():
 | 
			
		||||
        for platform_name, platform in hostOs.items():
 | 
			
		||||
            for toolchain_name, toolchain in platform.items():
 | 
			
		||||
                for project_name, project in toolchain.items():
 | 
			
		||||
                    if current_limit_count >= limit:
 | 
			
		||||
                        finish_ts_data(ts_data, project_run_data)
 | 
			
		||||
                        all_ts_data.append(ts_data)
 | 
			
		||||
                        ts_data = prep_ts_data()
 | 
			
		||||
                        current_limit_count = 0
 | 
			
		||||
                    
 | 
			
		||||
                    ts_data['projectRuns'].append(project)
 | 
			
		||||
                    ts_data['platforms'].add(platform_name)
 | 
			
		||||
                    ts_data['toolchains'].add(toolchain_name)
 | 
			
		||||
                    ts_data['names'].add(project_name)
 | 
			
		||||
                    ts_data['hostOses'].add(hostOs_name)
 | 
			
		||||
                    current_limit_count += 1
 | 
			
		||||
    
 | 
			
		||||
    if current_limit_count > 0:
 | 
			
		||||
        finish_ts_data(ts_data, project_run_data)
 | 
			
		||||
        all_ts_data.append(ts_data)
 | 
			
		||||
    
 | 
			
		||||
    return all_ts_data
 | 
			
		||||
 | 
			
		||||
def find_project_run(projectRuns, project):
 | 
			
		||||
    keys = ['hostOs', 'platform', 'toolchain', 'project']
 | 
			
		||||
 | 
			
		||||
    elem = projectRuns
 | 
			
		||||
 | 
			
		||||
    for key in keys:
 | 
			
		||||
        if not project[key] in elem:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        elem = elem[project[key]]
 | 
			
		||||
 | 
			
		||||
    return elem
 | 
			
		||||
 | 
			
		||||
def add_project_run(projectRuns, project):
 | 
			
		||||
    keys = ['hostOs', 'platform', 'toolchain']
 | 
			
		||||
 | 
			
		||||
    elem = projectRuns
 | 
			
		||||
 | 
			
		||||
    for key in keys:
 | 
			
		||||
        if not project[key] in elem:
 | 
			
		||||
            elem[project[key]] = {}
 | 
			
		||||
 | 
			
		||||
        elem = elem[project[key]]
 | 
			
		||||
 | 
			
		||||
    elem[project['project']] = project
 | 
			
		||||
 | 
			
		||||
def update_project_run_results(project_to_update, project, is_build):
 | 
			
		||||
    if is_build:
 | 
			
		||||
        project_to_update['buildPass'] = project['buildPass']
 | 
			
		||||
        project_to_update['buildResult'] = project['buildResult']
 | 
			
		||||
        project_to_update['buildOutput'] = project['buildOutput']
 | 
			
		||||
    else:
 | 
			
		||||
        project_to_update['testPass'] = project['testPass']
 | 
			
		||||
        project_to_update['testResult'] = project['testResult']
 | 
			
		||||
        project_to_update['testOutput'] = project['testOutput']
 | 
			
		||||
 | 
			
		||||
def update_project_run(projectRuns, project, is_build):
 | 
			
		||||
    found_project = find_project_run(projectRuns, project)
 | 
			
		||||
    if found_project:
 | 
			
		||||
        update_project_run_results(found_project, project, is_build)
 | 
			
		||||
    else:
 | 
			
		||||
        add_project_run(projectRuns, project)
 | 
			
		||||
 | 
			
		||||
def add_report(project_run_data, report_file, is_build, build_id, host_os):
 | 
			
		||||
    tree = None
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        tree = ET.parse(report_file)
 | 
			
		||||
    except:
 | 
			
		||||
        print(sys.exc_info()[0])
 | 
			
		||||
        print('Invalid path to report: %s', report_file)
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
    test_suites = tree.getroot()
 | 
			
		||||
 | 
			
		||||
    for test_suite in test_suites:
 | 
			
		||||
        platform = ""
 | 
			
		||||
        toolchain = ""
 | 
			
		||||
        vendor = ""
 | 
			
		||||
        for properties in test_suite.findall('properties'):
 | 
			
		||||
            for property in properties.findall('property'):
 | 
			
		||||
                if property.attrib['name'] == 'target':
 | 
			
		||||
                    platform = property.attrib['value']
 | 
			
		||||
                    project_run_data['platforms_set'].add(platform)
 | 
			
		||||
                elif property.attrib['name'] == 'toolchain':
 | 
			
		||||
                    toolchain = property.attrib['value']
 | 
			
		||||
                    project_run_data['toolchains_set'].add(toolchain)
 | 
			
		||||
                elif property.attrib['name'] == 'vendor':
 | 
			
		||||
                    vendor = property.attrib['value']
 | 
			
		||||
                    project_run_data['vendors_set'].add(vendor)
 | 
			
		||||
 | 
			
		||||
        for test_case in test_suite.findall('testcase'):
 | 
			
		||||
            projectRun = {}
 | 
			
		||||
            projectRun['build'] = build_id
 | 
			
		||||
            projectRun['hostOs'] = host_os
 | 
			
		||||
            projectRun['platform'] = platform
 | 
			
		||||
            projectRun['toolchain'] = toolchain
 | 
			
		||||
            projectRun['project'] = test_case.attrib['classname'].split('.')[-1]
 | 
			
		||||
            projectRun['vendor'] = vendor
 | 
			
		||||
 | 
			
		||||
            project_run_data['names_set'].add(projectRun['project'])
 | 
			
		||||
 | 
			
		||||
            should_skip = False
 | 
			
		||||
            skips = test_case.findall('skipped')
 | 
			
		||||
 | 
			
		||||
            if skips:
 | 
			
		||||
                should_skip = skips[0].attrib['message'] == 'SKIP'
 | 
			
		||||
 | 
			
		||||
            if not should_skip:
 | 
			
		||||
                system_outs = test_case.findall('system-out')
 | 
			
		||||
 | 
			
		||||
                output = ""
 | 
			
		||||
                if system_outs:
 | 
			
		||||
                    output = system_outs[0].text
 | 
			
		||||
 | 
			
		||||
                if is_build:
 | 
			
		||||
                    projectRun['buildOutput'] = output
 | 
			
		||||
                else:
 | 
			
		||||
                    projectRun['testOutput'] = output
 | 
			
		||||
 | 
			
		||||
                errors = test_case.findall('error')
 | 
			
		||||
                failures = test_case.findall('failure')
 | 
			
		||||
                projectRunPass = None
 | 
			
		||||
                result = None
 | 
			
		||||
 | 
			
		||||
                if errors:
 | 
			
		||||
                    projectRunPass = False
 | 
			
		||||
                    result = errors[0].attrib['message']
 | 
			
		||||
                elif failures:
 | 
			
		||||
                    projectRunPass = False
 | 
			
		||||
                    result = failures[0].attrib['message']
 | 
			
		||||
                elif skips:
 | 
			
		||||
                    projectRunPass = True
 | 
			
		||||
                    result = skips[0].attrib['message']
 | 
			
		||||
                else:
 | 
			
		||||
                    projectRunPass = True
 | 
			
		||||
                    result = 'OK'
 | 
			
		||||
 | 
			
		||||
                if is_build:
 | 
			
		||||
                    projectRun['buildPass'] = projectRunPass
 | 
			
		||||
                    projectRun['buildResult'] = result
 | 
			
		||||
                else:
 | 
			
		||||
                    projectRun['testPass'] = projectRunPass
 | 
			
		||||
                    projectRun['testResult'] = result
 | 
			
		||||
 | 
			
		||||
                update_project_run(project_run_data['projectRuns'], projectRun, is_build)
 | 
			
		||||
 | 
			
		||||
def main(arguments):
 | 
			
		||||
    # Register and parse command line arguments
 | 
			
		||||
    parser = argparse.ArgumentParser()
 | 
			
		||||
    parser.add_argument('-u', '--url', required=True, help='url to ci site')
 | 
			
		||||
    parser.add_argument('-k', '--api-key', required=True, help='api-key for posting data')
 | 
			
		||||
 | 
			
		||||
    subparsers = parser.add_subparsers(help='subcommand help')
 | 
			
		||||
 | 
			
		||||
    create_build_parser = subparsers.add_parser('create-build', help='create a new build')
 | 
			
		||||
    create_build_parser.add_argument('-b', '--build-number', required=True, help='build number')
 | 
			
		||||
    create_build_parser.add_argument('-T', '--build-type', choices=['Nightly', 'Limited', 'Pull_Request', 'Release_Candidate'], required=True, help='type of build')
 | 
			
		||||
    create_build_parser.add_argument('-s', '--build-source', required=True, help='url to source of build')
 | 
			
		||||
    create_build_parser.add_argument('-p', '--property-file-format', action='store_true', help='print result in the property file format')
 | 
			
		||||
    create_build_parser.set_defaults(func=create_build)
 | 
			
		||||
 | 
			
		||||
    finish_build_parser = subparsers.add_parser('finish-build', help='finish a running build')
 | 
			
		||||
    finish_build_parser.add_argument('-b', '--build-id', required=True, help='build id')
 | 
			
		||||
    finish_build_parser.set_defaults(func=finish_build)
 | 
			
		||||
 | 
			
		||||
    finish_build_parser = subparsers.add_parser('promote-build', help='promote a build to a release')
 | 
			
		||||
    finish_build_parser.add_argument('-b', '--build-id', required=True, help='build id')
 | 
			
		||||
    finish_build_parser.set_defaults(func=promote_build)
 | 
			
		||||
 | 
			
		||||
    abort_build_parser = subparsers.add_parser('abort-build', help='abort a running build')
 | 
			
		||||
    abort_build_parser.add_argument('-b', '--build-id', required=True, help='build id')
 | 
			
		||||
    abort_build_parser.set_defaults(func=abort_build)
 | 
			
		||||
 | 
			
		||||
    add_project_runs_parser = subparsers.add_parser('add-project-runs', help='add project runs to a build')
 | 
			
		||||
    add_project_runs_parser.add_argument('-b', '--build-id', required=True, help='build id')
 | 
			
		||||
    add_project_runs_parser.add_argument('-r', '--build-report', required=False, help='path to junit xml build report')
 | 
			
		||||
    add_project_runs_parser.add_argument('-t', '--test-report', required=False, help='path to junit xml test report')
 | 
			
		||||
    add_project_runs_parser.add_argument('-o', '--host-os', required=True, help='host os on which test was run')
 | 
			
		||||
    add_project_runs_parser.add_argument('-l', '--limit', required=False, type=int, default=1000, help='Limit the number of project runs sent at a time to avoid HTTP errors (default is 1000)')
 | 
			
		||||
    add_project_runs_parser.set_defaults(func=add_project_runs)
 | 
			
		||||
 | 
			
		||||
    args = parser.parse_args(arguments)
 | 
			
		||||
    args.func(args)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main(sys.argv[1:])
 | 
			
		||||
		Loading…
	
		Reference in New Issue