Exemplo n.º 1
0
 def should_run(self):
     """Indicate if the test should be run on current configuration."""
     supported_apis = graphics_utils.GraphicsApiHelper().get_supported_apis(
     )
     num_displays = graphics_utils.get_num_outputs_on()
     gpu_type = utils.get_gpu_family()
     soc = utils.get_cpu_soc_family()
     kernel_version = os.uname()[2]
     if num_displays == 0 and self._opts['display_required']:
         # If a test needs a display and we don't have a display,
         # consider it a pass.
         logging.warning('No display connected, skipping test.')
         return False
     if self._opts['vulkan_required'] and 'vk' not in supported_apis:
         # If a test needs vulkan to run and we don't have it,
         # consider it a pass
         logging.warning('Vulkan is required by test but is not '
                         'available on system. Skipping test.')
         return False
     if self._opts['min_kernel_version']:
         min_kernel_version = self._opts['min_kernel_version']
         if utils.compare_versions(kernel_version, min_kernel_version) < 0:
             logging.warning('Test requires kernel version >= %s,'
                             'have version %s. Skipping test.' %
                             (min_kernel_version, kernel_version))
             return False
     if self.name == 'atomictest' and gpu_type == 'baytrail':
         logging.warning('Baytrail is on kernel v4.4, but there is no '
                         'intention to enable atomic.')
         return False
     return True
Exemplo n.º 2
0
    def run_once(self, arc_mode=None):
        # If we are in arc_mode, do not report failures to perf dashboard.
        if arc_mode:
            self._test_failure_report_enable = False

        # We use kiosk mode to make sure Chrome is idle.
        self.add_failures('Graphics_Idle')
        with chrome.Chrome(logged_in=False,
                           extra_browser_args=['--kiosk'],
                           arc_mode=arc_mode):
            # Try to protect against runaway previous tests.
            if not utils.wait_for_idle_cpu(20.0, 0.1):
                logging.warning('Could not get idle CPU before running tests.')
            self._gpu_type = utils.get_gpu_family()
            self._cpu_type = utils.get_cpu_soc_family()
            self._board = utils.get_board()
            errors = ''
            errors += self.verify_graphics_dvfs()
            errors += self.verify_graphics_fbc()
            errors += self.verify_graphics_psr()
            errors += self.verify_graphics_gem_idle()
            errors += self.verify_graphics_i915_min_clock()
            errors += self.verify_graphics_rc6()
            errors += self.verify_lvds_downclock()
            errors += self.verify_short_blanking()
            if errors:
                raise error.TestFail('Failed: %s' % errors)
        self.remove_failures('Graphics_Idle')
Exemplo n.º 3
0
    def get_memory_keyvals(self):
        """
        Reads the graphics memory values and returns them as keyvals.
        """
        keyvals = {}

        # Get architecture type and list of sysfs fields to read.
        soc = utils.get_cpu_soc_family()

        arch = utils.get_cpu_arch()
        if arch == 'x86_64' or arch == 'i386':
            pci_vga_device = utils.run("lspci | grep VGA").stdout.rstrip('\n')
            if "Advanced Micro Devices" in pci_vga_device:
                soc = 'amdgpu'
            elif "Intel Corporation" in pci_vga_device:
                soc = 'i915'
            elif "Cirrus Logic" in pci_vga_device:
                # Used on qemu with kernels 3.18 and lower. Limited to 800x600
                # resolution.
                soc = 'cirrus'
            else:
                pci_vga_device = utils.run('lshw -c video').stdout.rstrip()
                groups = re.search('configuration:.*driver=(\S*)',
                                   pci_vga_device)
                if groups and 'virtio' in groups.group(1):
                    soc = 'virtio'

        if not soc in self.arch_fields:
            raise error.TestFail('Error: Architecture "%s" not yet supported.' % soc)
        fields = self.arch_fields[soc]

        for field_name in fields:
            possible_field_paths = fields[field_name]
            field_value = None
            for path in possible_field_paths:
                if utils.system('ls %s' % path):
                    continue
                field_value = utils.system_output('cat %s' % path)
                break

            if not field_value:
                logging.error('Unable to find any sysfs paths for field "%s"',
                              field_name)
                self.num_errors += 1
                continue

            parsed_results = GraphicsKernelMemory._parse_sysfs(field_value)

            for key in parsed_results:
                keyvals['%s_%s' % (field_name, key)] = parsed_results[key]

            if 'bytes' in parsed_results and parsed_results['bytes'] == 0:
                logging.error('%s reported 0 bytes', field_name)
                self.num_errors += 1

        keyvals['meminfo_MemUsed'] = (utils.read_from_meminfo('MemTotal') -
                                      utils.read_from_meminfo('MemFree'))
        keyvals['meminfo_SwapUsed'] = (utils.read_from_meminfo('SwapTotal') -
                                       utils.read_from_meminfo('SwapFree'))
        return keyvals
Exemplo n.º 4
0
    def run_once(self, arc_mode=None):
        # If we are in arc_mode, do not report failures to perf dashboard.
        if arc_mode:
            self._test_failure_report_enable = False

        self.add_failures('graphics_Idle')
        with chrome.Chrome(logged_in=True, arc_mode=arc_mode) as cr:
            # The New Tab Page contains the Google doodle which can cause
            # arbitrary side effects. Hide it by going to a neutral page.
            if not cr.browser.tabs:
                cr.browser.tabs.New()
            tab = cr.browser.tabs[0]
            tab.Navigate('chrome://version')
            # Try to protect against runaway previous tests.
            if not utils.wait_for_idle_cpu(60.0, 0.1):
                logging.warning('Could not get idle CPU before running tests.')
            self._gpu_type = utils.get_gpu_family()
            self._cpu_type = utils.get_cpu_soc_family()
            self._board = utils.get_board()
            errors = ''
            errors += self.verify_graphics_dvfs()
            errors += self.verify_graphics_fbc()
            errors += self.verify_graphics_psr()
            errors += self.verify_graphics_gem_idle()
            errors += self.verify_graphics_i915_min_clock()
            errors += self.verify_graphics_rc6()
            errors += self.verify_lvds_downclock()
            errors += self.verify_short_blanking()
            if errors:
                raise error.TestFail('Failed: %s' % errors)
        self.remove_failures('graphics_Idle')
Exemplo n.º 5
0
 def verify_graphics_rc6(self):
     """ On systems which support RC6 (non atom), check that we are able to
     get into rc6; idle before doing so, and retry every second for 20
     seconds."""
     logging.info('Running verify_graphics_rc6')
     # TODO(ihf): Implement on baytrail/braswell using residency counters.
     # But note the format changed since SNB, so this will be complex.
     if (utils.get_cpu_soc_family() == 'x86_64'
             and self._gpu_type != 'pinetrail'
             and self._gpu_type != 'baytrail'
             and self._gpu_type != 'braswell'):
         tries = 0
         found = False
         param_path = self.get_valid_path(RC6_PATHS)
         if not param_path:
             return 'RC6_PATHS not found.'
         while found == False and tries < 20:
             time.sleep(1)
             with open(param_path, 'r') as drpc_info_file:
                 for line in drpc_info_file:
                     match = re.search(r'Current RC state: (.*)', line)
                     if match and match.group(1) == 'RC6':
                         found = True
                         break
             tries += 1
         if not found:
             return self.handle_error('Error: did not see the GPU in RC6.',
                                      param_path)
     return ''
Exemplo n.º 6
0
    def verify_graphics_gem_idle(self):
        """ On systems which have i915, check that we can get all gem objects
        to become idle (i.e. the i915_gem_active list need to go to 0);
        idle before doing so, and retry every second for 20 seconds."""
        logging.info('Running verify_graphics_gem_idle')
        if (utils.get_cpu_soc_family() == 'x86_64'
                and self._gpu_type != 'pinetrail'):
            tries = 0
            found = False
            gem_path = self.get_valid_path(GEM_PATHS)
            if not gem_path:
                return 'GEM_PATHS not found.'
            while not found and tries < 240:
                time.sleep(0.25)
                with open(gem_path, 'r') as gem_file:
                    for line in gem_file:
                        if re.search('Total 0 objects', line):
                            found = True
                            break

                tries += 1

            if not found:
                utils.log_process_activity()
                logging.error('Error: did not reach 0 gem actives.')
                return 'Did not reach 0 gem actives. '

        return ''
Exemplo n.º 7
0
    def verify_graphics_psr(self):
        """ On systems which support PSR, check that we can get into PSR;
        idle before doing so, and retry every second for 20 seconds."""
        logging.info('Running verify_graphics_psr')

        if utils.get_cpu_soc_family() != 'x86_64':
            return ''
        tries = 0
        found = False
        param_path = self.get_valid_path(PSR_PATHS)
        if not param_path:
            logging.warning("PSR_PATHS not found.")
            return ''
        kernel_version = utils.get_kernel_version()[0:4].rstrip(".")
        logging.info('Kernel version: %s', kernel_version)
        # First check if PSR is enabled on the device so
        # we can watch for the active values
        with open(param_path, 'r') as psr_info_file:
            match = None
            for line in psr_info_file:
                match = re.search(r'Enabled: yes', line)
                if match:
                    logging.info('PSR enabled')
                    break
            if not match:
                logging.warning('PSR not enabled')
                return ''
        while not found and tries < 20:
            time.sleep(1)
            with open(param_path, 'r') as psr_info_file:
                for line in psr_info_file:
                    # Kernels 4.4 and up
                    if common_utils.compare_versions(kernel_version,
                                                     '4.4') != -1:
                        match = re.search(r'PSR status: .* \[SRDENT', line)
                        if match:
                            found = True
                            logging.info('Found active with kernel >= 4.4')
                            break
                    # 3.18 kernel
                    elif kernel_version == '3.18':
                        match = re.search(r'Performance_Counter: 0', line)
                        if match:
                            found = True
                            logging.info('Found active with 3.18 kernel')
                            break
                    # Older kernels (up to 3.14)
                    else:
                        match = re.search(r'Performance_Counter: ([\d])+',
                                          line)
                        if match and int(match.group(1)) > 0:
                            found = True
                            logging.info('Found active with kernel <= 3.14')
                            break

            tries += 1
        if not found:
            return self.handle_error('Did not see PSR activity. ', param_path)
        return ''
Exemplo n.º 8
0
    def run_once(self):
        num_errors = 0
        keyvals = {}

        # These are tests to run for all platforms.
        tests_common = ['modetest']

        # Determine which tests to run based on the architecture type.
        tests_exynos5 = ['kmstest']
        tests_mediatek = ['kmstest']
        tests_rockchip = ['kmstest']
        arch_tests = {
            'amd': [],
            'arm': [],
            'exynos5': tests_exynos5,
            'i386': [],
            'mediatek': tests_mediatek,
            'rockchip': tests_rockchip,
            'tegra': [],
            'x86_64': []
        }
        soc = utils.get_cpu_soc_family()
        if not soc in arch_tests:
            raise error.TestFail('Error: Architecture "%s" not supported.',
                                 soc)
        elif soc == 'tegra':
            logging.warning('Tegra does not support DRM.')
            return
        tests = tests_common + arch_tests[soc]

        # If UI is running, we must stop it and restore later.
        self._services.stop_services()

        for test in tests:
            # Make sure the test exists on this system.  Not all tests may be
            # present on a given system.
            if utils.system('which %s' % test):
                logging.error('Could not find test %s.', test)
                keyvals[test] = 'NOT FOUND'
                num_errors += 1
                continue

            # Run the test and check for success based on return value.
            return_value = utils.system(test)
            if return_value:
                logging.error('%s returned %d', test, return_value)
                num_errors += 1
                keyvals[test] = 'FAILED'
            else:
                keyvals[test] = 'PASSED'

        self.write_perf_keyval(keyvals)

        if num_errors > 0:
            raise error.TestFail('Failed: %d libdrm tests failed.' % num_errors)
Exemplo n.º 9
0
    def verify_graphics_gem_idle(self):
        """ On systems which have i915, check that we can get all gem objects
        to become idle (i.e. the i915_gem_active list or i915_gem_objects
        client/process gem object counts need to go to 0);
        idle before doing so, and retry every second for 20 seconds."""
        logging.info('Running verify_graphics_gem_idle')
        if utils.get_cpu_soc_family() == 'x86_64':
            tries = 0
            found = False
            per_process_check = False

            gem_path = self.get_valid_path(GEM_PATHS)
            if not gem_path:
                gem_path = self.get_valid_path(GEM_OBJECTS_PATHS)
                if gem_path:
                    per_process_check = True
                else:
                    return 'GEM_PATHS not found.'

            # Checks 4.4 and later kernels
            if per_process_check:
                while not found and tries < 240:
                    time.sleep(0.25)
                    gem_objects_idle = False
                    gem_active_search = False
                    with open(gem_path, 'r') as gem_file:
                        for line in gem_file:
                            if gem_active_search:
                                if re.search('\(0 active,', line):
                                    gem_objects_idle = True
                                else:
                                    gem_objects_idle = False
                                    break
                            elif line == '\n':
                                gem_active_search = True
                        if gem_objects_idle:
                            found = True
                    tries += 1

            # Checks pre 4.4 kernels
            else:
                while not found and tries < 240:
                    time.sleep(0.25)
                    with open(gem_path, 'r') as gem_file:
                        for line in gem_file:
                            if re.search('Total 0 objects', line):
                                found = True
                                break
                    tries += 1
            if not found:
                return self.handle_error('Did not reach 0 gem actives. ',
                                         gem_path)
        return ''
    def run_once(self, doctest=False):
        """
        Run the test.

        :param doctest: If true we will just run our doctests.  We'll set these
                        globals to help our tests:
                        - _testobj: An instance of this object.
                        - _info_io: A StringIO that's stuffed into logging.info
                          so we can see what was written there.
        ...
        """
        if doctest:
            import doctest, inspect, StringIO
            global _testobj, _info_io

            # Keep a backup of _get_regid_to_val() since tests will clobber.
            old_get_regid_to_val = self._get_regid_to_val

            # Mock out logging.info to help tests.
            _info_io = StringIO.StringIO()
            old_logging_info = logging.info
            logging.info = lambda fmt, *args: _info_io.write(fmt % args)

            # Stash an object in a global to help tests
            _testobj = self
            try:
                failure_count, test_count = doctest.testmod(
                    inspect.getmodule(self), optionflags=doctest.ELLIPSIS)
            finally:
                logging.info = old_logging_info

                # Technically don't need to clean this up, but let's be nice.
                self._get_regid_to_val = old_get_regid_to_val

            logging.info("Doctest ran %d tests, had %d failures",
                         test_count, failure_count)
            return

        if utils.get_cpu_soc_family() != 'arm':
            raise error.TestNAError('Applicable to ARM processors only')

        cpuinfo = self._parse_cpu_info(utils.read_file('/proc/cpuinfo'))

        for cpu_id in sorted(cpuinfo.keys()):
            self._check_one_cpu(cpuinfo[cpu_id])

        sys_power.do_suspend(self.SECS_TO_SUSPEND)

        for cpu_id in sorted(cpuinfo.keys()):
            self._check_one_cpu(cpuinfo[cpu_id])
Exemplo n.º 11
0
    def initialize(self):
        self._board = utils.get_board()
        self._cpu_type = utils.get_cpu_soc_family()
        self._gpu_type = utils.get_gpu_family()

        # deqp may depend on libraries that are present only on test images.
        # Those libraries are installed in /usr/local.
        self._env = os.environ.copy()
        old_ld_path = self._env.get('LD_LIBRARY_PATH', '')
        if old_ld_path:
            self._env[
                'LD_LIBRARY_PATH'] = '/usr/local/lib:/usr/local/lib64:' + old_ld_path
        else:
            self._env['LD_LIBRARY_PATH'] = '/usr/local/lib:/usr/local/lib64'

        # Determine which executable should be run. Right now never egl.
        major, minor = graphics_utils.get_gles_version()
        logging.info('Found gles%d.%d.', major, minor)
        if major is None or minor is None:
            raise error.TestFail(
                'Failed: Could not get gles version information (%d, %d).' %
                (major, minor))
        if major >= 2:
            self._can_run_executables.append('gles2/deqp-gles2')
        if major >= 3:
            self._can_run_executables.append('gles3/deqp-gles3')
            if major > 3 or minor >= 1:
                self._can_run_executables.append('gles31/deqp-gles31')

        # If libvulkan is installed, then assume the board supports vulkan.
        has_libvulkan = False
        for libdir in ('/usr/lib', '/usr/lib64', '/usr/local/lib',
                       '/usr/local/lib64'):
            if os.path.exists(os.path.join(libdir, 'libvulkan.so')):
                has_libvulkan = True

        if (has_libvulkan and os.path.exists(
                '/usr/local/deqp/external/vulkancts/modules/vulkan/deqp-vk')):
            self._can_run_executables.append(
                'external/vulkancts/modules/vulkan/deqp-vk')

        self._services = service_stopper.ServiceStopper(['ui', 'powerd'])
        # Valid choices are fbo and pbuffer. The latter avoids dEQP assumptions.
        self._surface = 'pbuffer'
Exemplo n.º 12
0
    def verify_graphics_i915_min_clock(self):
        """ On i915 systems, check that we get into the lowest clock frequency;
        idle before doing so, and retry every second for 20 seconds."""
        logging.info('Running verify_graphics_i915_min_clock')

        # TODO(benzh): enable once crbug.com/719040 is fixed.
        if self._gpu_type == 'baytrail' and utils.count_cpus() == 4:
            logging.info('Waived min clock check due to crbug.com/719040')
            return ''

        if (utils.get_cpu_soc_family() == 'x86_64'
                and self._gpu_type != 'pinetrail'):
            tries = 0
            found = False
            param_path = self.get_valid_path(CLOCK_PATHS)
            if not param_path:
                return 'CLOCK_PATHS not found.'
            while not found and tries < 80:
                time.sleep(0.25)

                with open(param_path, 'r') as delayinfo_file:
                    for line in delayinfo_file:
                        # This file has a different format depending on the
                        # board, so we parse both. Also, it would be tedious
                        # to add the minimum clock for each board, so instead
                        # we use 650MHz which is the max of the minimum clocks.
                        match = re.search(r'CAGF: (.*)MHz', line)
                        if match and int(match.group(1)) <= 650:
                            found = True
                            break

                        match = re.search(r'current GPU freq: (.*) MHz', line)
                        if match and int(match.group(1)) <= 650:
                            found = True
                            break

                tries += 1

            if not found:
                return self.handle_error('Did not see the min i915 clock. ',
                                         param_path)

        return ''
    def get_memory_keyvals(self):
        """
        Reads the graphics memory values and returns them as keyvals.
        """
        keyvals = {}

        # Get architecture type and list of sysfs fields to read.
        arch = utils.get_cpu_soc_family()

        if not arch in self.arch_fields:
            raise error.TestFail('Architecture "%s" not yet supported.' % arch)
        fields = self.arch_fields[arch]

        for field_name in fields:
            possible_field_paths = fields[field_name]
            field_value = None
            for path in possible_field_paths:
                if utils.system('ls %s' % path):
                    continue
                field_value = utils.system_output('cat %s' % path)
                break

            if not field_value:
                logging.error('Unable to find any sysfs paths for field "%s"',
                              field_name)
                self.num_errors += 1
                continue

            parsed_results = GraphicsKernelMemory._parse_sysfs(field_value)

            for key in parsed_results:
                keyvals['%s_%s' % (field_name, key)] = parsed_results[key]

            if 'bytes' in parsed_results and parsed_results['bytes'] == 0:
                logging.error('%s reported 0 bytes', field_name)
                self.num_errors += 1

        keyvals['meminfo_MemUsed'] = (utils.read_from_meminfo('MemTotal') -
                                      utils.read_from_meminfo('MemFree'))
        keyvals['meminfo_SwapUsed'] = (utils.read_from_meminfo('SwapTotal') -
                                       utils.read_from_meminfo('SwapFree'))
        return keyvals
Exemplo n.º 14
0
 def run_once(self):
     # Try to protect against runaway previous tests.
     if not utils.wait_for_idle_cpu(20.0, 0.1):
         logging.warning('Could not get idle CPU before running tests.')
     # We use kiosk mode to make sure Chrome is idle.
     with chrome.Chrome(logged_in=False, extra_browser_args=['--kiosk']):
         self._gpu_type = utils.get_gpu_family()
         self._cpu_type = utils.get_cpu_soc_family()
         self._board = utils.get_board()
         errors = ''
         errors += self.verify_graphics_dvfs()
         errors += self.verify_graphics_fbc()
         errors += self.verify_graphics_psr()
         errors += self.verify_graphics_gem_idle()
         errors += self.verify_graphics_i915_min_clock()
         errors += self.verify_graphics_rc6()
         errors += self.verify_lvds_downclock()
         errors += self.verify_short_blanking()
         if errors:
             raise error.TestFail(errors)
Exemplo n.º 15
0
    def initialize(self):
        super(graphics_dEQP, self).initialize()
        self._api_helper = graphics_utils.GraphicsApiHelper()
        self._board = utils.get_board()
        self._cpu_type = utils.get_cpu_soc_family()
        self._gpu_type = utils.get_gpu_family()

        # deqp may depend on libraries that are present only on test images.
        # Those libraries are installed in /usr/local.
        self._env = os.environ.copy()
        old_ld_path = self._env.get('LD_LIBRARY_PATH', '')
        if old_ld_path:
            self._env['LD_LIBRARY_PATH'] = '/usr/local/lib:/usr/local/lib64:' + old_ld_path
        else:
            self._env['LD_LIBRARY_PATH'] = '/usr/local/lib:/usr/local/lib64'

        self._services = service_stopper.ServiceStopper(['ui', 'powerd'])
        # Valid choices are fbo and pbuffer. The latter avoids dEQP assumptions.
        self._surface = 'pbuffer'
        self._services.stop_services()
    def run_once(self):
        """Runs the test."""
        arch = utils.get_cpu_arch()
        if arch == 'x86_64':
            arch = utils.get_cpu_soc_family()
        curr_kernel = utils.get_kernel_version()

        logging.debug('CPU arch is "%s"', arch)
        logging.debug('Kernel version is "%s"', curr_kernel)

        if arch not in self.TESTS:
            raise error.TestNAError('"%s" arch not in test baseline' % arch)

        # Kernels <= 3.14 don't have this directory and are expected to abort
        # with TestNA.
        if not os.path.exists(self.SYSTEM_CPU_VULNERABILITIES):
            raise error.TestNAError('"%s" directory not present, not testing' %
                                    self.SYSTEM_CPU_VULNERABILITIES)

        failures = []
        for filename, expected in self.TESTS[arch].items():
            file = os.path.join(self.SYSTEM_CPU_VULNERABILITIES, filename)
            if not os.path.exists(file):
                raise error.TestError('"%s" file does not exist, cannot test' %
                                      file)

            min_kernel = expected[0]
            if utils.compare_versions(curr_kernel, min_kernel) == -1:
                # The kernel on the DUT is older than the version where
                # the mitigation was introduced.
                info_message = 'DUT kernel version "%s"' % curr_kernel
                info_message += ' is older than "%s"' % min_kernel
                info_message += ', skipping "%s" test' % filename
                logging.info(info_message)
                continue

            # E.g.:
            # Not affected
            #   $ cat /sys/devices/system/cpu/vulnerabilities/meltdown
            #   Not affected
            #
            # One mitigation
            #   $ cat /sys/devices/system/cpu/vulnerabilities/meltdown
            #   Mitigation: PTI
            #
            # Several mitigations
            #   $ cat /sys/devices/system/cpu/vulnerabilities/spectre_v2
            #   Mitigation: Full generic retpoline, IBPB, IBRS_FW
            with open(file) as f:
                lines = f.readlines()
                if len(lines) > 1:
                    logging.warning('"%s" has more than one line', file)

                actual = lines[0].strip()
                logging.debug('"%s" -> "%s"', file, actual)

                expected_mitigations = expected[1]
                if not expected_mitigations:
                    if actual != 'Not affected':
                        failures.append((file, actual, expected_mitigations))
                else:
                    # CPU is affected.
                    if 'Mitigation' not in actual:
                        failures.append((file, actual, expected_mitigations))
                    else:
                        mit_list = actual.split(':', 1)[1].split(',')
                        actual_mitigations = set(t.strip() for t in mit_list)
                        # Test set inclusion.
                        if actual_mitigations < expected_mitigations:
                            failures.append((file, actual_mitigations,
                                             expected_mitigations))

        if failures:
            for failure in failures:
                logging.error('"%s" was "%s", expected "%s"', *failure)
            raise error.TestFail('CPU vulnerabilities not mitigated properly')
Exemplo n.º 17
0
 def initialize(self):
     self._gpu_type = utils.get_gpu_family()
     self._cpu_type = utils.get_cpu_soc_family()
     self._board = utils.get_board()
     self._services = service_stopper.ServiceStopper(['ui', 'powerd'])
Exemplo n.º 18
0
    def run_once(self, expect_me_present=True):
        """Fail unless the ME is locked.

        @param expect_me_present: False means the system has no ME.
        """
        cpu_arch = utils.get_cpu_arch()
        if cpu_arch == "arm":
            raise error.TestNAError(
                'This test is not applicable, '
                'because an ARM device has been detected. '
                'ARM devices do not have an ME (Management Engine)')

        cpu_family = utils.get_cpu_soc_family()
        if cpu_family == "amd":
            raise error.TestNAError(
                'This test is not applicable, '
                'because an AMD device has been detected. '
                'AMD devices do not have an ME (Management Engine)')

        # If sw wp is on, and the ME regions are unlocked, they won't be
        # writable so will appear locked.
        if self.determine_sw_wp_status():
            raise error.TestFail('Software wp is enabled. Please disable '
                                 'software wp prior to running this test.')

        # See if the system even has an ME, and whether we expected that.
        if self.has_ME():
            if not expect_me_present:
                raise error.TestFail('We expected no ME, but found one anyway')
        else:
            if expect_me_present:
                raise error.TestNAError("No ME found. That's probably wrong.")
            else:
                logging.info('We expected no ME and we have no ME, so pass.')
                return

        # Make sure manufacturing mode is off.
        self.check_manufacturing_mode()

        # Read the image using flashrom.
        self.flashrom(args=('-r', self.BIOS_FILE))

        # Use 'IFWI' fmap region as a proxy for a device which doesn't
        # have a dedicated ME region in the boot media.
        r = utils.run('dump_fmap', args=('-p', self.BIOS_FILE))
        is_IFWI_platform = r.stdout.find("IFWI") >= 0

        # Get the bios image and extract the ME components
        logging.info('Pull the ME components from the BIOS...')
        dump_fmap_args = ['-x', self.BIOS_FILE, 'SI_DESC']
        inaccessible_sections = []
        if is_IFWI_platform:
            inaccessible_sections.append('DEVICE_EXTENSION')
        else:
            inaccessible_sections.append('SI_ME')
        dump_fmap_args.extend(inaccessible_sections)
        utils.run('dump_fmap', args=tuple(dump_fmap_args))

        # So far, so good, but we need to be certain. Rather than parse what
        # flashrom tells us about the ME-related registers, we'll just try to
        # change the ME components. We shouldn't be able to.
        self.try_to_rewrite('SI_DESC')
        for sectname in inaccessible_sections:
            self.check_region_inaccessible(sectname)