Various CI fixes
* Output CSV on build stage
* Check more failure states in pipeline
* Allow configs.py to use multiple groups
* Add build log as artifact
* Add links to particular build configs
* Host CMSIS_5 pack file internally
* Adding mbedcrypto url as a param
* Move the LAVA job generation into a new jenkins job
* Make job_ids strings for adding to job description
Change-Id: I801a1a5d15a7f55e25477ad371e8ec59eb14fd7f
Signed-off-by: Dean Birch <dean.birch@arm.com>
diff --git a/lava_helper/jinja2_templates/template_tfm_mps2_fvp.jinja2 b/lava_helper/jinja2_templates/template_tfm_mps2_fvp.jinja2
new file mode 100644
index 0000000..aec5bd2
--- /dev/null
+++ b/lava_helper/jinja2_templates/template_tfm_mps2_fvp.jinja2
@@ -0,0 +1,77 @@
+{#------------------------------------------------------------------------------
+# Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-----------------------------------------------------------------------------#}
+{% extends 'jinja2_templates/base.jinja2' %}
+{% block metadata %}
+{{ super() }}
+{% endblock %}
+{% block base %}
+{{ super() }}
+{% endblock %}
+{% block actions %}
+context:
+ kernel_start_message: ''
+
+actions:
+- deploy:
+ namespace: docker
+ to: fvp
+ images:
+ ns:
+ url: {{ firmware_url }}
+ s:
+ url: {{ bootloader_url }}
+
+- boot:
+ namespace: docker
+ method: fvp
+ docker:
+ name: 'replace_docker_prefix/lava-fvp-mps2'
+ prompts:
+ - 'root@lava '
+ image: /opt/model/FVP_MPS2_AEMv8M
+ timeout:
+ minutes: 5
+ console_string: 'telnetterminal0: Listening for serial connection on port (?P<PORT>\d+)'
+ license_variable: 'replace_licence_variable'
+ arguments:
+ - "--application cpu0={S}"
+ - "--data cpu0={NS}@0x00100000"
+ - "--simlimit 1200"
+ - "--parameter fvp_mps2.platform_type=2"
+ - "--parameter cpu0.INITVTOR_S=0x10000000"
+ - "--parameter cpu0.semihosting-enable=0"
+ - "--parameter fvp_mps2.DISABLE_GATING=0"
+ - "--parameter fvp_mps2.telnetterminal0.start_telnet=1"
+ - "--parameter fvp_mps2.telnetterminal1.start_telnet=1"
+ - "--parameter fvp_mps2.telnetterminal2.start_telnet=1"
+ - "--parameter fvp_mps2.telnetterminal0.quiet=0"
+ - "--parameter fvp_mps2.telnetterminal1.quiet=0"
+ - "--parameter fvp_mps2.telnetterminal2.quiet=0"
+ - "--parameter fvp_mps2.UART0.unbuffered_output=1"
+ - "--parameter fvp_mps2.UART0.shutdown_on_eot=1"
+ - "--parameter fvp_mps2.UART1.unbuffered_output=1"
+ - "--parameter fvp_mps2.UART1.shutdown_on_eot=1"
+ - "--parameter fvp_mps2.UART2.unbuffered_output=1"
+ - "--parameter fvp_mps2.UART2.shutdown_on_eot=1"
+ - "--parameter fvp_mps2.mps2_visualisation.disable-visualisation=1"
+ - "--parameter cpu0.baseline=1"
+ prompts:
+ - 'Jumping to non-secure code'
+
+- test:
+ namespace: target
+ monitors:
+ {%- for monitor in test.monitors %}
+ - name: "{{monitor.name}}_{{ platform }}_{{ compiler }}_{{ name }}_{{ build_type }}_{{ boot_type }}"
+ start: "{{monitor.start}}"
+ end: "{{monitor.end}}"
+ pattern: "{{monitor.pattern}}"
+ fixupdict:
+ '{{monitor.fixup.pass}}': pass
+ '{{monitor.fixup.fail}}': fail
+ {% endfor %}
+{% endblock %}
diff --git a/lava_helper/lava_helper_configs.py b/lava_helper/lava_helper_configs.py
index b1ddd4e..888b0f9 100644
--- a/lava_helper/lava_helper_configs.py
+++ b/lava_helper/lava_helper_configs.py
@@ -172,8 +172,137 @@
} # Tests
}
+
+tfm_mps2_fvp = {
+ "templ": "template_tfm_mps2_fvp.jinja2",
+ "job_name": "mps-fvp",
+ "device_type": "fvp",
+ "job_timeout": 180,
+ "action_timeout": 90,
+ "monitor_timeout": 90,
+ "poweroff_timeout": 5,
+ "recovery_store_url": "%(jenkins_url)s/"
+ "job/%(jenkins_job)s",
+ "artifact_store_url": "%(jenkins_url)s/"
+ "job/%(jenkins_job)s",
+ "platforms": {"AN519": "mps2_an521_v3.0.tar.gz"},
+ "compilers": ["GNUARM"],
+ "build_types": ["Debug", "Release"],
+ "boot_types": ["BL2"],
+ "tests": {
+ 'Default': {
+ "binaries": {
+ "firmware": "tfm_s.axf",
+ "bootloader": "tfm_ns.bin"
+ },
+ "monitors": [
+ {
+ 'name': 'Secure_Test_Suites_Summary',
+ 'start': '[Sec Thread]',
+ 'end': '\\x1b\\\[0m',
+ 'pattern': r'\x1b\\[1;34m\\[Sec Thread\\] '
+ r'(?P<test_case_id>Secure image '
+ r'initializing)(?P<result>!)',
+ 'fixup': {"pass": "!", "fail": ""},
+ 'required': ["secure_image_initializing"]
+ } # Monitors
+ ]
+ }, # Default
+ 'Regression': {
+ "binaries": {
+ "firmware": "tfm_s.axf",
+ "bootloader": "tfm_ns.bin"
+ },
+ "monitors": [
+ {
+ 'name': 'Secure_Test_Suites_Summary',
+ 'start': 'Secure test suites summary',
+ 'end': 'End of Secure test suites',
+ 'pattern': r"[\x1b]\\[37mTest suite '(?P<"
+ r"test_case_id>[^\n]+)' has [\x1b]\\[32m "
+ r"(?P<result>PASSED|FAILED)",
+ 'fixup': {"pass": "PASSED", "fail": "FAILED"},
+ 'required': [
+ ("psa_protected_storage_"
+ "s_interface_tests_tfm_sst_test_2xxx_"),
+ "sst_reliability_tests_tfm_sst_test_3xxx_",
+ "sst_rollback_protection_tests_tfm_sst_test_4xxx_",
+ ("psa_internal_trusted_storage_"
+ "s_interface_tests_tfm_its_test_2xxx_"),
+ "its_reliability_tests_tfm_its_test_3xxx_",
+ ("audit_"
+ "logging_secure_interface_test_tfm_audit_test_1xxx_"),
+ "crypto_secure_interface_tests_tfm_crypto_test_5xxx_",
+ ("initial_attestation_service_"
+ "secure_interface_tests_tfm_attest_test_1xxx_"),
+ ]
+ },
+ {
+ 'name': 'Non_Secure_Test_Suites_Summary',
+ 'start': 'Non-secure test suites summary',
+ 'end': r'End of Non-secure test suites',
+ 'pattern': r"[\x1b]\\[37mTest suite '(?P"
+ r"<test_case_id>[^\n]+)' has [\x1b]\\[32m "
+ r"(?P<result>PASSED|FAILED)",
+ 'fixup': {"pass": "PASSED", "fail": "FAILED"},
+ 'required': [
+ ("psa_protected_storage"
+ "_ns_interface_tests_tfm_sst_test_1xxx_"),
+ ("psa_internal_trusted_storage"
+ "_ns_interface_tests_tfm_its_test_1xxx_"),
+ ("auditlog_"
+ "non_secure_interface_test_tfm_audit_test_1xxx_"),
+ ("crypto_"
+ "non_secure_interface_test_tfm_crypto_test_6xxx_"),
+ ("initial_attestation_service_"
+ "non_secure_interface_tests_tfm_attest_test_2xxx_"),
+ "core_non_secure_positive_tests_tfm_core_test_1xxx_"
+ ]
+ }
+ ] # Monitors
+ }, # Regression
+ 'CoreIPC': {
+ "binaries": {
+ "firmware": "tfm_s.axf",
+ "bootloader": "tfm_ns.bin"
+ },
+ "monitors": [
+ {
+ 'name': 'Secure_Test_Suites_Summary',
+ 'start': '[Sec Thread]',
+ 'end': '\\x1b\\\[0m',
+ 'pattern': r'\x1b\\[1;34m\\[Sec Thread\\] '
+ r'(?P<test_case_id>Secure image '
+ r'initializing)(?P<result>!)',
+ 'fixup': {"pass": "!", "fail": ""},
+ 'required': ["secure_image_initializing"]
+ } # Monitors
+ ]
+ }, # CoreIPC
+ 'CoreIPCTfmLevel2': {
+ "binaries": {
+ "firmware": "tfm_s.axf",
+ "bootloader": "tfm_ns.bin"
+ },
+ "monitors": [
+ {
+ 'name': 'Secure_Test_Suites_Summary',
+ 'start': '[Sec Thread]',
+ 'end': '\\x1b\\\[0m',
+ 'pattern': r'\x1b\\[1;34m\\[Sec Thread\\] '
+ r'(?P<test_case_id>Secure image '
+ r'initializing)(?P<result>!)',
+ 'fixup': {"pass": "!", "fail": ""},
+ 'required': ["secure_image_initializing"]
+ } # Monitors
+ ]
+ }, # CoreIPCTfmLevel2
+ } # Tests
+}
+
# All configurations should be mapped here
-lava_gen_config_map = {"tfm_mps2_sse_200": tfm_mps2_sse_200}
+lava_gen_config_map = {"tfm_mps2_sse_200": tfm_mps2_sse_200,
+ "tfm_mps2_fvp": tfm_mps2_fvp}
lavagen_config_sort_order = [
"templ",
"job_name",
diff --git a/lava_helper/lava_submit_jobs.py b/lava_helper/lava_submit_jobs.py
new file mode 100755
index 0000000..b52bed1
--- /dev/null
+++ b/lava_helper/lava_submit_jobs.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+
+from __future__ import print_function
+
+"""
+Script for submitting multiple LAVA definitions
+"""
+
+__copyright__ = """
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+ """
+
+import os
+import glob
+import sys
+import shutil
+import argparse
+from copy import deepcopy
+from collections import OrderedDict
+from jinja2 import Environment, FileSystemLoader
+from lava_helper_configs import *
+
+try:
+ from tfm_ci_pylib.utils import (
+ save_json,
+ load_json,
+ sort_dict,
+ load_yaml,
+ test,
+ print_test,
+ )
+ from tfm_ci_pylib.lava_rpc_connector import LAVA_RPC_connector
+except ImportError:
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ sys.path.append(os.path.join(dir_path, "../"))
+ from tfm_ci_pylib.utils import (
+ save_json,
+ load_json,
+ sort_dict,
+ load_yaml,
+ test,
+ print_test,
+ )
+ from tfm_ci_pylib.lava_rpc_connector import LAVA_RPC_connector
+
+
+def test_lava_dispatch_credentials(user_args):
+ """ Will validate if provided token/credentials are valid. It will return
+ a valid connection or exit program if not"""
+
+ # Collect the authentication tokens
+ try:
+ if user_args.token_from_env:
+ usr = os.environ['LAVA_USER']
+ secret = os.environ['LAVA_TOKEN']
+ elif user_args.lava_token and user_args.lava_user:
+ usr = user_args.lava_user
+ secret = user_args.lava_token
+
+ # Do not submit job without complete credentials
+ if not len(usr) or not len(secret):
+ raise Exception("Credentials not set")
+
+ lava = LAVA_RPC_connector(usr,
+ secret,
+ user_args.lava_url)
+
+ # Test the credentials againist the backend
+ if not lava.test_credentials():
+ raise Exception("Server rejected user authentication")
+ except Exception as e:
+ print("Credential validation failed with : %s" % e)
+ print("Did you set set --lava-token, --lava-user?")
+ sys.exit(1)
+ return lava
+
+def list_files_from_dir(user_args):
+ file_list = []
+ for filename in glob.iglob(user_args.job_dir + '**/*.yaml', recursive=True):
+ file_list.append(filename)
+ print("Found job {}".format(filename))
+ return file_list
+
+def lava_dispatch(user_args):
+ """ Submit a job to LAVA backend, block untill it is completed, and
+ fetch the results files if successful. If not, calls sys exit with 1
+ return code """
+
+ lava = test_lava_dispatch_credentials(user_args)
+ file_list = list_files_from_dir(user_args)
+ job_id_list = []
+ for job_file in file_list:
+ job_id, job_url = lava.submit_job(job_file)
+
+ # The reason of failure will be reported to user by LAVA_RPC_connector
+ if job_id is None and job_url is None:
+ print("Job failed")
+ else:
+ print("Job submitted at: " + job_url)
+ job_id_list.append(job_id)
+
+ print("\n".join(str(x) for x in job_id_list))
+
+def main(user_args):
+ lava_dispatch(user_args)
+
+
+def get_cmd_args():
+ """ Parse command line arguments """
+
+ # Parse command line arguments to override config
+ parser = argparse.ArgumentParser(description="Lava Create Jobs")
+ cmdargs = parser.add_argument_group("Create LAVA Jobs")
+
+ # Configuration control
+ cmdargs.add_argument(
+ "--lava-url", dest="lava_url", action="store", help="LAVA lab URL (without RPC2)"
+ )
+ cmdargs.add_argument(
+ "--job-dir", dest="job_dir", action="store", help="LAVA jobs directory"
+ )
+ cmdargs.add_argument(
+ "--lava-token", dest="lava_token", action="store", help="LAVA auth token"
+ )
+ cmdargs.add_argument(
+ "--lava-user", dest="lava_user", action="store", help="LAVA username"
+ )
+ cmdargs.add_argument(
+ "--use-env", dest="token_from_env", action="store_true", default=False, help="LAVA username"
+ )
+ cmdargs.add_argument(
+ "--lava-timeout", dest="dispatch_timeout", action="store", default=3600, help="LAVA username"
+ )
+ return parser.parse_args()
+
+
+if __name__ == "__main__":
+ main(get_cmd_args())