mirror of https://github.com/ARMmbed/mbed-os.git
359 lines
9.5 KiB
Python
359 lines
9.5 KiB
Python
# Copyright (c) 2018, Arm Limited and affiliates.
|
|
# 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.
|
|
|
|
"""
|
|
This module contains classes to represent Test Specification interface that
|
|
defines the data to be generated by/from a build system to give enough information
|
|
to Greentea.
|
|
"""
|
|
|
|
import json
|
|
|
|
|
|
class TestBinary(object):
|
|
"""
|
|
Class representing a Test Binary.
|
|
"""
|
|
|
|
KW_BIN_TYPE = "binary_type"
|
|
KW_BIN_PATH = "path"
|
|
KW_COMP_LOG = "compare_log"
|
|
|
|
BIN_TYPE_BOOTABLE = "bootable"
|
|
BIN_TYPE_DEFAULT = BIN_TYPE_BOOTABLE
|
|
SUPPORTED_BIN_TYPES = [BIN_TYPE_BOOTABLE]
|
|
|
|
def __init__(self, path, binary_type, compare_log):
|
|
"""
|
|
ctor.
|
|
|
|
:param path:
|
|
:param binary_type:
|
|
:return:
|
|
"""
|
|
assert binary_type in TestBinary.SUPPORTED_BIN_TYPES, (
|
|
"Binary type %s not supported. Supported types [%s]"
|
|
% (binary_type, ", ".join(TestBinary.SUPPORTED_BIN_TYPES))
|
|
)
|
|
self.__path = path
|
|
self.__flash_method = binary_type
|
|
self.__comp_log = compare_log
|
|
|
|
def get_path(self):
|
|
"""
|
|
Gives binary path.
|
|
:return:
|
|
"""
|
|
return self.__path
|
|
|
|
def get_compare_log(self):
|
|
"""
|
|
Gives compare log file.
|
|
:return:
|
|
"""
|
|
return self.__comp_log
|
|
|
|
|
|
class Test(object):
|
|
"""
|
|
class representing a Test artifact that may contain more than one test binaries.
|
|
"""
|
|
|
|
KW_TEST_NAME = "name"
|
|
KW_TEST_BINS = "binaries"
|
|
|
|
def __init__(self, name, default_flash_method=None):
|
|
"""
|
|
ctor.
|
|
|
|
:param name:
|
|
:param default_flash_method:
|
|
:return:
|
|
"""
|
|
self.__name = name
|
|
self.__default_flash_method = default_flash_method
|
|
self.__binaries_by_flash_method = {}
|
|
|
|
def get_name(self):
|
|
"""
|
|
Gives test name.
|
|
|
|
:return:
|
|
"""
|
|
return self.__name
|
|
|
|
def get_binary(self, binary_type=TestBinary.BIN_TYPE_DEFAULT):
|
|
"""
|
|
Gives a test binary of specific flash type.
|
|
|
|
:param binary_type:
|
|
:return:
|
|
"""
|
|
return self.__binaries_by_flash_method.get(binary_type, None)
|
|
|
|
def parse(self, test_json):
|
|
"""
|
|
Parse json contents into object.
|
|
|
|
:param test_json:
|
|
:return:
|
|
"""
|
|
assert Test.KW_TEST_BINS in test_json, "Test spec should contain key `binaries`"
|
|
for binary in test_json[Test.KW_TEST_BINS]:
|
|
mandatory_keys = [TestBinary.KW_BIN_PATH]
|
|
assert set(mandatory_keys).issubset(
|
|
set(binary.keys())
|
|
), "Binary spec should contain key [%s]" % ",".join(mandatory_keys)
|
|
fm = binary.get(TestBinary.KW_BIN_TYPE, self.__default_flash_method)
|
|
assert fm is not None, "Binary type not specified in build and binary spec."
|
|
tb = TestBinary(binary[TestBinary.KW_BIN_PATH],
|
|
fm,
|
|
binary.get(TestBinary.KW_COMP_LOG))
|
|
self.__binaries_by_flash_method[fm] = tb
|
|
|
|
def add_binary(self, path, binary_type, compare_log=None):
|
|
"""
|
|
Add binary to the test.
|
|
|
|
:param path:
|
|
:param binary_type:
|
|
:return:
|
|
"""
|
|
self.__binaries_by_flash_method[binary_type] = TestBinary(path,
|
|
binary_type,
|
|
compare_log)
|
|
|
|
|
|
class TestBuild(object):
|
|
"""
|
|
class for Test build.
|
|
"""
|
|
|
|
KW_TEST_BUILD_NAME = "name"
|
|
KW_PLATFORM = "platform"
|
|
KW_TOOLCHAIN = "toolchain"
|
|
KW_BAUD_RATE = "baud_rate"
|
|
KW_BUILD_BASE_PATH = "base_path"
|
|
KW_TESTS = "tests"
|
|
KW_BIN_TYPE = "binary_type"
|
|
|
|
def __init__(
|
|
self, name, platform, toolchain, baud_rate, base_path, default_flash_method=None
|
|
):
|
|
"""
|
|
ctor.
|
|
|
|
:param name:
|
|
:param platform:
|
|
:param toolchain:
|
|
:param baud_rate:
|
|
:param base_path:
|
|
:param default_flash_method:
|
|
:return:
|
|
"""
|
|
self.__name = name
|
|
self.__platform = platform
|
|
self.__toolchain = toolchain
|
|
self.__baud_rate = baud_rate
|
|
self.__base_path = base_path
|
|
self.__default_flash_method = default_flash_method
|
|
self.__tests = {}
|
|
|
|
def get_name(self):
|
|
"""
|
|
Gives build name.
|
|
|
|
:return:
|
|
"""
|
|
return self.__name
|
|
|
|
def get_platform(self):
|
|
"""
|
|
Gives mbed classic platform name.
|
|
|
|
:return:
|
|
"""
|
|
return self.__platform
|
|
|
|
def get_toolchain(self):
|
|
"""
|
|
Gives toolchain
|
|
|
|
:return:
|
|
"""
|
|
return self.__toolchain
|
|
|
|
def get_baudrate(self):
|
|
"""
|
|
Gives baud rate.
|
|
|
|
:return:
|
|
"""
|
|
return self.__baud_rate
|
|
|
|
def get_path(self):
|
|
"""
|
|
Gives path.
|
|
|
|
:return:
|
|
"""
|
|
return self.__base_path
|
|
|
|
def get_tests(self):
|
|
"""
|
|
Gives tests dict keyed by test name.
|
|
|
|
:return:
|
|
"""
|
|
return self.__tests
|
|
|
|
def parse(self, build_spec):
|
|
"""
|
|
Parse Test build json.
|
|
|
|
:param build_spec:
|
|
:return:
|
|
"""
|
|
assert TestBuild.KW_TESTS in build_spec, (
|
|
"Build spec should contain key '%s'" % TestBuild.KW_TESTS
|
|
)
|
|
for name, test_json in build_spec[TestBuild.KW_TESTS].items():
|
|
test = Test(name, default_flash_method=self.__default_flash_method)
|
|
test.parse(test_json)
|
|
self.__tests[name] = test
|
|
|
|
def add_test(self, name, test):
|
|
"""
|
|
Add test.
|
|
|
|
:param name:
|
|
:param test:
|
|
:return:
|
|
"""
|
|
self.__tests[name] = test
|
|
|
|
|
|
class TestSpec(object):
|
|
"""
|
|
Test specification. Contains Builds.
|
|
"""
|
|
|
|
KW_BUILDS = "builds"
|
|
test_spec_filename = "runtime_load"
|
|
|
|
def __init__(self, test_spec_filename=None):
|
|
"""
|
|
ctor.
|
|
|
|
:return:
|
|
"""
|
|
self.__target_test_spec = {}
|
|
if test_spec_filename:
|
|
self.test_spec_filename = test_spec_filename
|
|
self.load(self.test_spec_filename)
|
|
|
|
def load(self, test_spec_filename):
|
|
"""
|
|
Load test spec directly from file
|
|
|
|
:param test_spec_filename: Name of JSON file with TestSpec to load
|
|
:return: Treu if load was successful
|
|
"""
|
|
try:
|
|
with open(test_spec_filename, "r") as f:
|
|
self.parse(json.load(f))
|
|
except Exception as e:
|
|
print("TestSpec::load('%s') %s" % (test_spec_filename, str(e)))
|
|
return False
|
|
|
|
self.test_spec_filename = test_spec_filename
|
|
return True
|
|
|
|
def parse(self, spec):
|
|
"""
|
|
Parse test spec json.
|
|
|
|
:param spec:
|
|
:return:
|
|
"""
|
|
assert TestSpec.KW_BUILDS, (
|
|
"Test spec should contain key '%s'" % TestSpec.KW_BUILDS
|
|
)
|
|
for build_name, build in spec[TestSpec.KW_BUILDS].items():
|
|
mandatory_keys = [
|
|
TestBuild.KW_PLATFORM,
|
|
TestBuild.KW_TOOLCHAIN,
|
|
TestBuild.KW_BAUD_RATE,
|
|
TestBuild.KW_BUILD_BASE_PATH,
|
|
]
|
|
assert set(mandatory_keys).issubset(set(build.keys())), (
|
|
"Build spec should contain keys [%s]. It has [%s]"
|
|
% (",".join(mandatory_keys), ",".join(build.keys()))
|
|
)
|
|
platform = build[TestBuild.KW_PLATFORM]
|
|
toolchain = build[TestBuild.KW_TOOLCHAIN]
|
|
|
|
# If there is no 'name' property in build, we will use build key
|
|
# as build name
|
|
name = build.get(TestBuild.KW_TEST_BUILD_NAME, build_name)
|
|
|
|
tb = TestBuild(
|
|
name,
|
|
platform,
|
|
toolchain,
|
|
build[TestBuild.KW_BAUD_RATE],
|
|
build[TestBuild.KW_BUILD_BASE_PATH],
|
|
build.get(TestBuild.KW_BIN_TYPE, None),
|
|
)
|
|
tb.parse(build)
|
|
self.__target_test_spec[name] = tb
|
|
|
|
def get_test_builds(self, filter_by_names=None):
|
|
"""
|
|
Gives test builds.
|
|
:param filter_by_names: List of names of builds you want to filter
|
|
in your result
|
|
:return:
|
|
"""
|
|
result = []
|
|
if filter_by_names:
|
|
assert type(filter_by_names) is list
|
|
for tb in self.__target_test_spec.values():
|
|
if tb.get_name() in filter_by_names:
|
|
result.append(tb)
|
|
else:
|
|
# When filtering by name is not defined we will return all builds objects
|
|
result = list(self.__target_test_spec.values())
|
|
return result
|
|
|
|
def get_test_build(self, build_name):
|
|
"""
|
|
Gives test build with given name.
|
|
|
|
:param build_name:
|
|
:return:
|
|
"""
|
|
return self.__target_test_spec.get(build_name, None)
|
|
|
|
def add_test_builds(self, name, test_build):
|
|
"""
|
|
Add test build.
|
|
|
|
:param name:
|
|
:param test_build:
|
|
:return:
|
|
"""
|
|
self.__target_test_spec[name] = test_build
|