xref: /aosp_15_r20/external/autotest/server/cros/tradefed/cts_expected_failure_parser.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python2, python3
2# Copyright 2017 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import logging
7import yaml
8
9class ParseKnownCTSFailures(object):
10    """A class to parse known failures in CTS test."""
11
12    def __init__(self, failure_files):
13        self.waivers_yaml = self._load_failures(failure_files)
14
15    def _validate_waiver_config(self,
16                                arch,
17                                board,
18                                model,
19                                bundle_abi,
20                                sdk_ver,
21                                first_api_level,
22                                config,
23                                extra_dut_config=[]):
24        """Validate if the test environment matches the test config.
25
26        @param arch: DUT's arch type.
27        @param board: DUT's board name.
28        @paran model: DUT's model name.
29        @param bundle_abi: The test's abi type.
30        @param sdk_ver: DUT's Android SDK version
31        @param first_api_level: DUT's Android first API level.
32        @param config: config for an expected failing test.
33        @param extra_dut_config: list of DUT configs added from _get_extra_dut_config(host).
34        @return True if test arch or board is part of the config, else False.
35        """
36        # Map only the versions that ARC releases care.
37        sdk_ver_map = {25: 'N', 28: 'P', 30: 'R', 33: 'T'}
38
39        # 'all' applies to all devices.
40        # 'x86' or 'arm' applies to the DUT's architecture.
41        # board name like 'eve' or 'kevin' applies to the DUT running the board.
42        dut_config = ['all', arch, board, model]
43        dut_config.extend(extra_dut_config)
44        # 'binarytranslated' applies to the case running ARM CTS on x86 devices.
45        if bundle_abi and bundle_abi[0:3] != arch:
46            dut_config.append('binarytranslated')
47        # 'N' or 'P' or 'R' applies to the device running that Android version.
48        if sdk_ver in sdk_ver_map:
49            dut_config.append(sdk_ver_map[sdk_ver])
50        # 'shipatN' or 'shipatP' or 'shipatR' applies to those originally
51        # launched at that Android version.
52        if first_api_level in sdk_ver_map:
53            dut_config.append('shipat' + sdk_ver_map[first_api_level])
54        return len(set(dut_config).intersection(config)) > 0
55
56    def _get_extra_dut_config(self, host):
57        """
58        @param host: DUT to be connected. Passed for additional params.
59        """
60        extra_dut_config = []
61        # some modules are notest if ARC hardware vulkan exists.
62        if host.has_arc_hardware_vulkan():
63            extra_dut_config.append('vulkan')
64        # some modules are notest if there is no ARC hardware vulkan.
65        else:
66            extra_dut_config.append('no_vulkan')
67        return extra_dut_config
68
69    def _load_failures(self, failure_files):
70        """Load failures from files.
71
72        @param failure_files: files with failure configs.
73        @return a dictionary of failures config in yaml format.
74        """
75        waivers_yaml = {}
76        for failure_file in failure_files:
77            try:
78                logging.info('Loading expected failure file: %s.', failure_file)
79                with open(failure_file) as wf:
80                    waivers_yaml.update(yaml.safe_load(wf.read()))
81            except IOError as e:
82                logging.error('Error loading %s (%s).',
83                              failure_file,
84                              e.strerror)
85                continue
86            logging.info('Finished loading expected failure file: %s',
87                         failure_file)
88        return waivers_yaml
89
90    def find_waivers(self,
91                     arch,
92                     board,
93                     model,
94                     bundle_abi,
95                     sdk_ver,
96                     first_api_level,
97                     host=None):
98        """Finds waivers for the test board.
99
100        @param arch: DUT's arch type.
101        @param board: DUT's board name.
102        @param model: DUT's model name.
103        @param bundle_abi: The test's abi type.
104        @param sdk_ver: DUT's Android SDK version.
105        @param first_api_level: DUT's Android first API level.
106        @param host: DUT to be connected. Passed for additional params.
107        @return a set of waivers/no-test-modules applied to the test board.
108        """
109        applied_waiver_list = set()
110        extra_dut_config = self._get_extra_dut_config(host)
111        for test, config in self.waivers_yaml.items():
112            if self._validate_waiver_config(arch, board, model, bundle_abi,
113                                            sdk_ver, first_api_level, config,
114                                            extra_dut_config):
115                applied_waiver_list.add(test)
116        logging.info('Excluding tests/packages from rerun: %s.',
117                     applied_waiver_list)
118        return applied_waiver_list
119