1*ac13d5f3SPatrick Williams# This class contains the common logic to deploy the SystemReady ACS pre-built 2*ac13d5f3SPatrick Williams# image and set up the testimage environment. It is to be inherited by recipes 3*ac13d5f3SPatrick Williams# which contains the URI to download the SystemReady ACS image. 4*ac13d5f3SPatrick Williams# This class also contains a testimage "postfunc" called acs_logs_handle which 5*ac13d5f3SPatrick Williams# performs the following functions after the tests have completed: 6*ac13d5f3SPatrick Williams# * Extract the acs_results directory from the Wic image to 7*ac13d5f3SPatrick Williams# ${WORKDIR}/testimage 8*ac13d5f3SPatrick Williams# * Create a symlink to the acs_results in ${TMPDIR}/log/oeqa for ease of 9*ac13d5f3SPatrick Williams# access 10*ac13d5f3SPatrick Williams# * Run the test parser, format results, and check results routines 11*ac13d5f3SPatrick Williams 12*ac13d5f3SPatrick WilliamsINHIBIT_DEFAULT_DEPS = "1" 13*ac13d5f3SPatrick WilliamsCOMPATIBLE_HOST = "aarch64-*" 14*ac13d5f3SPatrick WilliamsPACKAGE_ARCH = "${MACHINE_ARCH}" 15*ac13d5f3SPatrick Williamsinherit nopackages deploy rootfs-postcommands ${IMAGE_CLASSES} python3native 16*ac13d5f3SPatrick Williams 17*ac13d5f3SPatrick Williamsdo_configure[noexec] = "1" 18*ac13d5f3SPatrick Williamsdo_compile[noexec] = "1" 19*ac13d5f3SPatrick Williamsdo_install[noexec] = "1" 20*ac13d5f3SPatrick Williamsdo_testimage[depends] += "mtools-native:do_populate_sysroot" 21*ac13d5f3SPatrick Williams 22*ac13d5f3SPatrick Williams# Deploy with this suffix so it is picked up in the machine configuration 23*ac13d5f3SPatrick WilliamsIMAGE_DEPLOY_SUFFIX ?= ".wic" 24*ac13d5f3SPatrick Williams 25*ac13d5f3SPatrick Williams# Post-process commands may write to IMGDEPLOYDIR 26*ac13d5f3SPatrick WilliamsIMGDEPLOYDIR = "${DEPLOYDIR}" 27*ac13d5f3SPatrick Williams# Write the test data in IMAGE_POSTPROCESS_COMMAND 28*ac13d5f3SPatrick WilliamsIMAGE_POSTPROCESS_COMMAND += "write_image_test_data; " 29*ac13d5f3SPatrick Williams 30*ac13d5f3SPatrick Williamspython do_deploy() { 31*ac13d5f3SPatrick Williams deploydir = d.getVar('DEPLOYDIR') 32*ac13d5f3SPatrick Williams suffix = d.getVar('IMAGE_DEPLOY_SUFFIX') 33*ac13d5f3SPatrick Williams imgfile = os.path.join(d.getVar('WORKDIR'), d.getVar('IMAGE_FILENAME')) 34*ac13d5f3SPatrick Williams deployfile = os.path.join(deploydir, d.getVar('IMAGE_NAME') + suffix) 35*ac13d5f3SPatrick Williams linkfile = os.path.join(deploydir, d.getVar('IMAGE_LINK_NAME') + suffix) 36*ac13d5f3SPatrick Williams 37*ac13d5f3SPatrick Williams # Install the image file in the deploy directory 38*ac13d5f3SPatrick Williams import shutil 39*ac13d5f3SPatrick Williams shutil.copyfile(imgfile, deployfile) 40*ac13d5f3SPatrick Williams if os.path.lexists(linkfile): 41*ac13d5f3SPatrick Williams os.remove(manifest_link) 42*ac13d5f3SPatrick Williams os.symlink(os.path.basename(deployfile), linkfile) 43*ac13d5f3SPatrick Williams 44*ac13d5f3SPatrick Williams # Run the image post-process commands 45*ac13d5f3SPatrick Williams from oe.utils import execute_pre_post_process 46*ac13d5f3SPatrick Williams post_process_cmds = d.getVar("IMAGE_POSTPROCESS_COMMAND") 47*ac13d5f3SPatrick Williams execute_pre_post_process(d, post_process_cmds) 48*ac13d5f3SPatrick Williams 49*ac13d5f3SPatrick Williams # Copy the report.txt to DEPLOYDIR 50*ac13d5f3SPatrick Williams # The machine-specific implementation can optionally put the report file in 51*ac13d5f3SPatrick Williams # ${WORKDIR}/report.txt. If there is no such file present, use the template. 52*ac13d5f3SPatrick Williams workdir = d.getVar('WORKDIR') 53*ac13d5f3SPatrick Williams report_file = os.path.join(workdir, "report.txt") 54*ac13d5f3SPatrick Williams report_file_dest = os.path.join(deploydir, "report.txt") 55*ac13d5f3SPatrick Williams if os.path.exists(report_file): 56*ac13d5f3SPatrick Williams report_file_to_copy = report_file 57*ac13d5f3SPatrick Williams else: 58*ac13d5f3SPatrick Williams report_file_to_copy = os.path.join(workdir, "systemready-ir-template", 59*ac13d5f3SPatrick Williams "report.txt") 60*ac13d5f3SPatrick Williams shutil.copyfile(report_file_to_copy, report_file_dest) 61*ac13d5f3SPatrick Williams 62*ac13d5f3SPatrick Williams # Ensure an empty rootfs manifest exists (required by testimage) 63*ac13d5f3SPatrick Williams fname = os.path.join(deploydir, d.getVar('IMAGE_LINK_NAME') + ".manifest") 64*ac13d5f3SPatrick Williams open(fname, 'w').close() 65*ac13d5f3SPatrick Williams} 66*ac13d5f3SPatrick Williamsaddtask deploy after do_install before do_image_complete 67*ac13d5f3SPatrick Williams 68*ac13d5f3SPatrick Williamsdo_image_complete() { 69*ac13d5f3SPatrick Williams true 70*ac13d5f3SPatrick Williams} 71*ac13d5f3SPatrick Williamsaddtask image_complete after do_deploy before do_build 72*ac13d5f3SPatrick Williamsdo_image_complete[depends] += "arm-systemready-firmware:do_image_complete" 73*ac13d5f3SPatrick Williams 74*ac13d5f3SPatrick WilliamsACS_LOG_NAME = "acs_results_${DATETIME}" 75*ac13d5f3SPatrick WilliamsACS_LOG_NAME[vardepsexclude] += "DATETIME" 76*ac13d5f3SPatrick WilliamsACS_LOG_DIR = "${TEST_LOG_DIR}/${ACS_LOG_NAME}" 77*ac13d5f3SPatrick WilliamsACS_LOG_LINK = "${TEST_LOG_DIR}/acs_results" 78*ac13d5f3SPatrick WilliamsTEST_LOG_DIR = "${WORKDIR}/testimage" 79*ac13d5f3SPatrick WilliamsRM_WORK_EXCLUDE_ITEMS += "${@ os.path.basename(d.getVar('TEST_LOG_DIR')) }" 80*ac13d5f3SPatrick Williams 81*ac13d5f3SPatrick Williamsdo_testimage[postfuncs] += "acs_logs_handle" 82*ac13d5f3SPatrick Williamsdo_testimage[depends] += "edk2-test-parser-native:do_populate_sysroot \ 83*ac13d5f3SPatrick Williams arm-systemready-scripts-native:do_populate_sysroot" 84*ac13d5f3SPatrick Williams 85*ac13d5f3SPatrick Williams# Process the logs 86*ac13d5f3SPatrick Williamspython acs_logs_handle() { 87*ac13d5f3SPatrick Williams import logging 88*ac13d5f3SPatrick Williams from oeqa.utils import make_logger_bitbake_compatible 89*ac13d5f3SPatrick Williams import shutil 90*ac13d5f3SPatrick Williams 91*ac13d5f3SPatrick Williams deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE') 92*ac13d5f3SPatrick Williams systemready_scripts_dir = os.path.join(d.getVar('STAGING_LIBDIR_NATIVE'), 93*ac13d5f3SPatrick Williams "systemready_scripts") 94*ac13d5f3SPatrick Williams edk2_test_parser_dir = os.path.join(d.getVar('STAGING_LIBDIR_NATIVE'), 95*ac13d5f3SPatrick Williams "edk2_test_parser") 96*ac13d5f3SPatrick Williams deployfile = os.path.join(deploy_dir_image, d.getVar('IMAGE_LINK_NAME') 97*ac13d5f3SPatrick Williams + d.getVar('IMAGE_DEPLOY_SUFFIX')) 98*ac13d5f3SPatrick Williams 99*ac13d5f3SPatrick Williams testimage_dir = d.getVar('TEST_LOG_DIR') 100*ac13d5f3SPatrick Williams logdir = d.getVar('ACS_LOG_DIR') 101*ac13d5f3SPatrick Williams loglink = d.getVar('ACS_LOG_LINK') 102*ac13d5f3SPatrick Williams 103*ac13d5f3SPatrick Williams # Copy the report.txt file from DEPLOY_DIR_IMAGE 104*ac13d5f3SPatrick Williams report_file = os.path.join(deploy_dir_image, "report.txt") 105*ac13d5f3SPatrick Williams report_file_dest = os.path.join(testimage_dir, "report.txt") 106*ac13d5f3SPatrick Williams shutil.copyfile(report_file, report_file_dest) 107*ac13d5f3SPatrick Williams 108*ac13d5f3SPatrick Williams # Extract the log files from the Wic image to the testimage logs directory 109*ac13d5f3SPatrick Williams resultspath = deployfile + ':3/acs_results' 110*ac13d5f3SPatrick Williams import subprocess 111*ac13d5f3SPatrick Williams subprocess.run(['wic', 'cp', resultspath, logdir], check=True) 112*ac13d5f3SPatrick Williams 113*ac13d5f3SPatrick Williams # Create a symlink to the acs_results directory 114*ac13d5f3SPatrick Williams if os.path.lexists(loglink): 115*ac13d5f3SPatrick Williams os.remove(loglink) 116*ac13d5f3SPatrick Williams os.symlink(os.path.basename(logdir), loglink) 117*ac13d5f3SPatrick Williams 118*ac13d5f3SPatrick Williams # Create a top-level symlink to the acs_results directory 119*ac13d5f3SPatrick Williams top_logdir = os.path.join(get_testimage_json_result_dir(d), d.getVar("PN")) 120*ac13d5f3SPatrick Williams log_name = d.getVar('ACS_LOG_NAME') 121*ac13d5f3SPatrick Williams top_link = os.path.join(top_logdir, log_name) 122*ac13d5f3SPatrick Williams log_target = os.path.relpath(logdir, top_logdir) 123*ac13d5f3SPatrick Williams os.symlink(log_target, top_link) 124*ac13d5f3SPatrick Williams 125*ac13d5f3SPatrick Williams # Parse the logs and generate results file 126*ac13d5f3SPatrick Williams logger = make_logger_bitbake_compatible(logging.getLogger("BitBake")) 127*ac13d5f3SPatrick Williams 128*ac13d5f3SPatrick Williams sct_log = os.path.join(logdir, 'sct_results', 'Overall', 'Summary.ekl') 129*ac13d5f3SPatrick Williams sct_seq = os.path.join(logdir, 'sct_results', 'Sequence', 'EBBR.seq') 130*ac13d5f3SPatrick Williams 131*ac13d5f3SPatrick Williams parser_path = os.path.join(edk2_test_parser_dir, "parser.py") 132*ac13d5f3SPatrick Williams # format-sr-results.py needs the output file to be called "result.md" 133*ac13d5f3SPatrick Williams subprocess.run([parser_path, sct_log, sct_seq, "--md", 134*ac13d5f3SPatrick Williams os.path.join(logdir, "result.md")], check=True) 135*ac13d5f3SPatrick Williams 136*ac13d5f3SPatrick Williams scripts_path = os.path.join(systemready_scripts_dir, 137*ac13d5f3SPatrick Williams "format-sr-results.py") 138*ac13d5f3SPatrick Williams summary_path = os.path.join(testimage_dir, "summary.md") 139*ac13d5f3SPatrick Williams subprocess.run([scripts_path, "--dir", testimage_dir, "--md", summary_path], 140*ac13d5f3SPatrick Williams check=True) 141*ac13d5f3SPatrick Williams 142*ac13d5f3SPatrick Williams # Symlink acs-console.log to default_log 143*ac13d5f3SPatrick Williams subprocess.run(["ln", "-sf", os.path.join(testimage_dir, "default_log"), 144*ac13d5f3SPatrick Williams os.path.join(testimage_dir, "acs-console.log")], check=True) 145*ac13d5f3SPatrick Williams 146*ac13d5f3SPatrick Williams # Run the check-sr-results.py systemready script to check the results 147*ac13d5f3SPatrick Williams check_sr_results_log_path = os.path.join(testimage_dir, 148*ac13d5f3SPatrick Williams "check_sr_results.log") 149*ac13d5f3SPatrick Williams with open(check_sr_results_log_path, "w") as f: 150*ac13d5f3SPatrick Williams check_sr_results_path = os.path.join(systemready_scripts_dir, 151*ac13d5f3SPatrick Williams "check-sr-results.py") 152*ac13d5f3SPatrick Williams try: 153*ac13d5f3SPatrick Williams subprocess.run([check_sr_results_path, "--dir", testimage_dir, 154*ac13d5f3SPatrick Williams "--print-meta", "--debug"], 155*ac13d5f3SPatrick Williams stdout=f, stderr=f, text=True, check=True) 156*ac13d5f3SPatrick Williams except subprocess.CalledProcessError: 157*ac13d5f3SPatrick Williams logger.error(f"ACS run failed the check SystemReady results. See " 158*ac13d5f3SPatrick Williams f"{summary_path} and {check_sr_results_log_path} for " 159*ac13d5f3SPatrick Williams f"details of the error.") 160*ac13d5f3SPatrick Williams raise bb.BBHandledException() 161*ac13d5f3SPatrick Williams} 162