xref: /openbmc/openbmc/meta-arm/meta-arm-systemready/classes/arm-systemready-acs.bbclass (revision ac13d5f36a6bd845f1709b7f41c02bd3b412ad15)
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