<commit_before># Copyright 2015 ARM Limited, All rights reserved
#
# 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.
"""


class TestBinary:
    """
    Class representing a Test Binary.
    """
    KW_BIN_TYPE = "binary_type"
    KW_BIN_PATH = "path"

    BIN_TYPE_BOOTABLE = "bootable"
    BIN_TYPE_DEFAULT = BIN_TYPE_BOOTABLE
    SUPPORTED_BIN_TYPES = [BIN_TYPE_BOOTABLE]

    def __init__(self, path, binary_type):
        """
        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

    def get_path(self):
        """
        Gives binary path.
        :return:
        """
        return self.__path


class Test:
    """
    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)
            self.__binaries_by_flash_method[fm] = tb

    def add_binary(self, path, binary_type):
        """
        Add binary to the test.

        :param path:
        :param binary_type:
        :return:
        """
        self.__binaries_by_flash_method[binary_type] = TestBinary(path, binary_type)


class TestBuild:
    """
    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].iteritems():
            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:
    """
    Test specification. Contains Builds.
    """
    KW_BUILDS = "builds"

    def __init__(self):
        """
        ctor.

        :return:
        """
        self.__target_test_spec = {}

    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].iteritems():
            mandatory_keys = [TestBuild.KW_PLATFORM, TestBuild.KW_TOOLCHAIN,
                              TestBuild.KW_BAUD_RATE,
                              TestBuild.KW_BUILD_BASE_PATH]
            print set(mandatory_keys)
            print set(build.keys())
            print set(mandatory_keys).issubset(set(build.keys()))
            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):
        """
        Gives test builds.
        :return:<commit_msg>Remove debug prints from test_spec<commit_after># Copyright 2015 ARM Limited, All rights reserved
#
# 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.
"""


class TestBinary:
    """
    Class representing a Test Binary.
    """
    KW_BIN_TYPE = "binary_type"
    KW_BIN_PATH = "path"

    BIN_TYPE_BOOTABLE = "bootable"
    BIN_TYPE_DEFAULT = BIN_TYPE_BOOTABLE
    SUPPORTED_BIN_TYPES = [BIN_TYPE_BOOTABLE]

    def __init__(self, path, binary_type):
        """
        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

    def get_path(self):
        """
        Gives binary path.
        :return:
        """
        return self.__path


class Test:
    """
    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)
            self.__binaries_by_flash_method[fm] = tb

    def add_binary(self, path, binary_type):
        """
        Add binary to the test.

        :param path:
        :param binary_type:
        :return:
        """
        self.__binaries_by_flash_method[binary_type] = TestBinary(path, binary_type)


class TestBuild:
    """
    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].iteritems():
            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:
    """
    Test specification. Contains Builds.
    """
    KW_BUILDS = "builds"

    def __init__(self):
        """
        ctor.

        :return:
        """
        self.__target_test_spec = {}

    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].iteritems():
            mandatory_keys = [TestBuild.KW_PLATFORM, TestBuild.KW_TOOLCHAIN,
                              TestBuild.KW_BAUD_RATE,
                              TestBuild.KW_BUILD_BASE_PATH]
            #print set(mandatory_keys)
            #print set(build.keys())
            #print set(mandatory_keys).issubset(set(build.keys()))
            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):
        """
        Gives test builds.
        :return:
{'fraction_non_alphanumeric': 0.09438638799571275, 'fraction_numerical': 0.0010718113612004287, 'mean_word_length': 2.0312690355329948, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2238332', 'n_tokens_mistral': 4496, 'n_tokens_neox': 4363, 'n_words': 1107}