Ejemplo n.º 1
0
    def test_screen_with_image(self, expected_resolution, test_mirrored=None,
                               error_list=None, chameleon_supported=True,
                               retry_count=2):
        """Tests the screen with image loaded.

        @param expected_resolution: A tuple (width, height) for the expected
                                    resolution.
        @param test_mirrored: True to test mirrored mode. False not to. None
                              to test mirrored mode iff the current mode is
                              mirrored.
        @param error_list: A list to append the error message to or None.
        @param retry_count: A count to retry the screen test.
        @param chameleon_supported: Whether resolution is supported by
                                    chameleon. The DP RX doesn't support
                                    4K resolution. The max supported resolution
                                    is 2560x1600. See crbug/585900.
        @return: None if the check passes; otherwise, a string of error message.
        """
        if test_mirrored is None:
            test_mirrored = self._display_facade.is_mirrored_enabled()

        if test_mirrored:
            test_image_size = self._display_facade.get_internal_resolution()
        else:
            # DUT needs time to respond to the plug event
            test_image_size = utils.wait_for_value_changed(
                    self._display_facade.get_external_resolution,
                    old_value=None)
        error = None
        if test_image_size != expected_resolution:
            error = ('Screen size %s is not as expected %s!'
                     % (str(test_image_size), str(expected_resolution)))
            if test_mirrored:
                # For the case of mirroring, depending on hardware vs
                # software mirroring, screen size can be different.
                logging.info('Warning: %s', error)
                error = None
            else:
                error_list.append(error)

        if chameleon_supported:
            error = self._resolution_comparer.compare(expected_resolution)
            if not error:
                while retry_count:
                    retry_count = retry_count - 1
                    try:
                        self.load_test_image(test_image_size)
                        error = self.test_screen(expected_resolution, test_mirrored)
                        if error is None:
                            return error
                        elif retry_count > 0:
                            logging.info('Retry screen comparison again...')
                    finally:
                        self.unload_test_image()

            if error and error_list is not None:
                error_list.append(error)
        return error
    def run_once(self, host, edid_set):

        def _get_edid_type(s):
            i = s.rfind('_') + 1
            j = len(s) - len('.txt')
            return s[i:j].upper()

        edid_path = os.path.join(self.bindir, 'test_data', 'edids',
                                 edid_set, '*')

        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.setup_and_reset(self.outputdir)
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
                chameleon_board, display_facade)
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                chameleon_port, display_facade, self.outputdir)

            logging.info('See the display on Chameleon: port %d (%s)',
                         chameleon_port.get_connector_id(),
                         chameleon_port.get_connector_type())

            connector = chameleon_port.get_connector_type()
            supported_types = self._EDID_TYPES[connector]

            failed_edids = []
            for filepath in glob.glob(edid_path):
                filename = os.path.basename(filepath)
                edid_type = _get_edid_type(filename)
                if edid_type not in supported_types:
                    logging.info('Skip EDID: %s...', filename)
                    continue

                logging.info('Use EDID: %s...', filename)
                try:
                    with chameleon_port.use_edid(
                            edid.Edid.from_file(filepath, skip_verify=True)):
                        resolution = utils.wait_for_value_changed(
                                display_facade.get_external_resolution,
                                old_value=None)
                        if resolution is None:
                            raise error.TestFail('No external display detected on DUT')
                        if screen_test.test_resolution(resolution):
                            raise error.TestFail('Resolution test failed')
                except (error.TestFail, xmlrpclib.Fault) as e:
                    logging.warning(e)
                    logging.error('EDID not supported: %s', filename)
                    failed_edids.append(filename)

            if failed_edids:
                message = ('Total %d EDIDs not supported: ' % len(failed_edids)
                           + ', '.join(failed_edids))
                logging.error(message)
                raise error.TestFail(message)
    def _wait_for_brightness_change(self, timeout):
        """Return screen brightness on update, or current value on timeout.

        @returns float of screen brightness percentage.

        """
        initial_brightness = self._backlight.get_percent()
        current_brightness = utils.wait_for_value_changed(
            lambda: self._backlight.get_percent(),
            old_value=initial_brightness,
            timeout_sec=timeout)
        if current_brightness != initial_brightness:
            time.sleep(self.SCREEN_SETTLE_TIME)
            current_brightness = self._backlight.get_percent()
        return current_brightness
 def action_download_omaha_component(self):
     """
     Pretend we have no system Flash binary and tell browser to
     accelerate the component update process.
     TODO(ihf): Is this better than pretending the system binary is old?
     """
     # TODO(ihf): Find ways to test component updates on top of component
     # updates maybe by checking hashlib.md5(open(_COMPONENT_STORE_LATEST)).
     if os.path.exists(_COMPONENT_STORE):
         raise error.TestFail('Error: currently unable to test component '
                              'update as component store not clean before '
                              'download.')
     # TODO(ihf): Remove --component-updater=test-request once Finch is set
     # up to behave more like a user in the field.
     browser_args = [
         '--ppapi-flash-path=', '--ppapi-flash-version=0.0.0.0',
         '--component-updater=fast-update,test-request'
     ]
     logging.info(browser_args)
     # Browser will download component, but it will require a subsequent
     # reboot by the caller to use it. (Browser restart is not enough.)
     with chrome.Chrome(extra_browser_args=browser_args,
                        init_network_controller=True) as cr:
         self.serve_swf_to_browser(cr.browser)
         # Wait for the last file to be written by component updater.
         utils.wait_for_value_changed(
             lambda: (os.path.exists(_COMPONENT_STORE_LATEST)),
             False,
             timeout_sec=self._component_download_timeout_secs)
         if not os.path.exists(_COMPONENT_STORE):
             raise error.TestFail('Failed: after download no component at '
                                  '%s' % _COMPONENT_STORE)
         # This may look silly but we prefer giving the system a bit more
         # time to write files to disk before subsequent reboot.
         os.system('sync')
         time.sleep(10)
    def test_screen_with_image(self, expected_resolution, test_mirrored=None,
                               error_list=None, retry_count=2):
        """Tests the screen with image loaded.

        @param expected_resolution: A tuple (width, height) for the expected
                                    resolution.
        @param test_mirrored: True to test mirrored mode. False not to. None
                              to test mirrored mode iff the current mode is
                              mirrored.
        @param error_list: A list to append the error message to or None.
        @param retry_count: A count to retry the screen test.
        @return: None if the check passes; otherwise, a string of error message.
        """
        if test_mirrored is None:
            test_mirrored = self._display_facade.is_mirrored_enabled()

        if test_mirrored:
            test_image_size = self._display_facade.get_internal_resolution()
        else:
            # DUT needs time to respond to the plug event
            test_image_size = utils.wait_for_value_changed(
                    self._display_facade.get_external_resolution,
                    old_value=None)

        error = self._resolution_comparer.compare(expected_resolution)
        if not error:
            while retry_count:
                retry_count = retry_count - 1
                try:
                    self.load_test_image(test_image_size)
                    error = self.test_screen(expected_resolution, test_mirrored)
                    if error is None:
                        return error
                    elif retry_count > 0:
                        logging.info('Retry screen comparison again...')
                finally:
                    self.unload_test_image()

        if error and error_list is not None:
            error_list.append(error)
        return error
Ejemplo n.º 6
0
    def run_once(self, host, test_mirrored=False):
        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.setup_and_reset(self.outputdir)
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
            chameleon_board, display_facade)

        errors = []
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                host, chameleon_port, display_facade, self.outputdir)

            with chameleon_port.use_edid(edid.NO_EDID):
                connector_name = utils.wait_for_value_changed(
                    display_facade.get_external_connector_name,
                    old_value=False)
                if not connector_name:
                    error_message = 'Failed to detect display without an EDID'
                    logging.error(error_message)
                    errors.append(error_message)
                    continue

                logging.info('Set mirrored: %s', test_mirrored)
                display_facade.set_mirrored(test_mirrored)

                resolution = display_facade.get_external_resolution()
                if resolution not in self.STANDARD_MODE_RESOLUTIONS:
                    error_message = ('Switched to a non-standard mode: %r' %
                                     resolution)
                    logging.error(error_message)
                    errors.append(error_message)
                    continue

                screen_test.test_screen_with_image(resolution, test_mirrored,
                                                   errors)

        if errors:
            raise error.TestFail('; '.join(set(errors)))
    def run_once(self, host, test_mirrored=False, testcase_spec=None,
                 repeat_count=3, suspend_time_range=(5,7)):
        if test_mirrored and not host.get_board_type() == 'CHROMEBOOK':
            raise error.TestNAError('DUT is not Chromebook. Test Skipped')

        if testcase_spec is None:
            testcase_spec = self.DEFAULT_TESTCASE_SPEC

        test_name = "%s_%dx%d" % testcase_spec
        _, width, height = testcase_spec
        test_resolution = (width, height)

        if not edid.is_edid_supported(host, testcase_spec[1], testcase_spec[2]):
            raise error.TestFail('Error: EDID is not supported by the platform'
                    ': %s', test_name)

        edid_path = os.path.join(self.bindir, 'test_data', 'edids', test_name)

        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.setup_and_reset(self.outputdir)
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
                chameleon_board, display_facade)
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                    chameleon_port, display_facade, self.outputdir)

            logging.info('Use EDID: %s', test_name)
            with chameleon_port.use_edid_file(edid_path):
                # Keep the original connector name, for later comparison.
                expected_connector = utils.wait_for_value_changed(
                        display_facade.get_external_connector_name,
                        old_value=False)
                logging.info('See the display on DUT: %s', expected_connector)

                if not expected_connector:
                    raise error.TestFail('Error: Failed to see external display'
                            ' (chameleon) from DUT: %s', test_name)

                logging.info('Set mirrored: %s', test_mirrored)
                display_facade.set_mirrored(test_mirrored)
                logging.info('Repeat %d times Suspend and resume', repeat_count)

                count = repeat_count
                while count > 0:
                    count -= 1
                    if test_mirrored:
                        # magic sleep to make nyan_big wake up in mirrored mode
                        # TODO: find root cause
                        time.sleep(6)
                    suspend_time = random.randint(*suspend_time_range)
                    logging.info('Going to suspend, for %d seconds...',
                                 suspend_time)
                    display_facade.suspend_resume(suspend_time)
                    logging.info('Resumed back')

                    message = screen_test.check_external_display_connected(
                            expected_connector)
                    if not message:
                        message = screen_test.test_screen_with_image(
                                test_resolution, test_mirrored)
                    if message:
                        raise error.TestFail(message)
    def run_once(self, host, test_mirrored=False, resolution_list=None):
        if not host.get_board_type() == 'CHROMEBOOK':
            raise error.TestNAError('DUT is not Chromebook. Test Skipped')
        if resolution_list is None:
            resolution_list = self.DEFAULT_RESOLUTION_LIST
        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.reset()
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
                chameleon_board, display_facade)

        errors = []
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                    chameleon_port, display_facade, self.outputdir)
            chameleon_port_name = chameleon_port.get_connector_type()
            logging.info('Detected %s chameleon port.', chameleon_port_name)
            for interface, width, height in resolution_list:
                if not chameleon_port_name.startswith(interface):
                    continue
                test_resolution = (width, height)
                test_name = "%s_%dx%d" % ((interface,) + test_resolution)

                if not edid.is_edid_supported(host, interface, width, height):
                    logging.info('Skip unsupported EDID: %s', test_name)
                    continue
                edid_path = os.path.join(self.bindir, 'test_data', 'edids',
                                    test_name)

                logging.info('Use EDID: %s', test_name)

                with chameleon_port.use_edid_file(edid_path):
                    index = utils.wait_for_value_changed(
                            display_facade.get_first_external_display_index,
                            old_value=False)
                    if not index:
                        raise error.TestFail("No external display is found.")

                    # In mirror mode only display index is '0', as external
                    # is treated same as internal(single resolution applies)
                    if test_mirrored:
                        index = 0
                    logging.info('Set mirrored: %s', test_mirrored)
                    display_facade.set_mirrored(test_mirrored)
                    settings_resolution_list = (
                            display_facade.get_available_resolutions(index))
                    if len(settings_resolution_list) == 0:
                        raise error.TestFail("No resolution list is found.")
                    logging.info('External display %d: %d resolutions found.',
                                index, len(settings_resolution_list))

                    for r in settings_resolution_list:
                        # FIXME: send a keystroke to keep display on.
                        # This is to work around a problem where the display may be
                        # turned off if the test has run for a long time (e.g.,
                        # greater than 15 min). When the display is off,
                        # set_resolution() will fail.
                        display_facade.hide_cursor()

                        logging.info('Set resolution to %dx%d', *r)
                        display_facade.set_resolution(index, *r)
                        time.sleep(self.RESOLUTION_CHANGE_TIME)

                        chameleon_port.wait_video_input_stable()
                        screen_test.test_screen_with_image(r, test_mirrored, errors)

            if errors:
                raise error.TestFail('; '.join(set(errors)))
Ejemplo n.º 9
0
    def run_flash_sanity_test(self, browser, time_to_wait_secs):
        """Run the Flash sanity test.

        @param browser: The Browser object to run the test with.
        @param time_to_wait_secs: wait time for swf file to load.

        """
        tab = None
        # BUG(485108): Work around a telemetry timing out after login.
        try:
            logging.info('Getting tab from telemetry...')
            tab = browser.tabs[0]
        except:
            logging.warning('Unexpected exception getting tab: %s',
                            pprint.pformat(sys.exc_info()[0]))
        if tab is None:
            return False

        logging.info('Initialize reading system logs.')
        self._messages_log_reader = cros_logging.LogReader()
        self._messages_log_reader.set_start_by_current()
        self._ui_log_reader = cros_logging.LogReader('/var/log/ui/ui.LATEST')
        self._ui_log_reader.set_start_by_current()
        logging.info('Done initializing system logs.')

        # Ensure that the swf got pulled.
        pulled = False
        try:
            latch = self._testServer.add_wait_url('/Trivial.swf')
            tab.Navigate(self._test_url)
            tab.WaitForDocumentReadyStateToBeComplete()
            logging.info('Waiting up to %ds for document.', time_to_wait_secs)
            latch.wait(time_to_wait_secs)
            pulled = True
        except:
            logging.warning('Unexpected exception wating for document: %s',
                            pprint.pformat(sys.exc_info()[0]))
        if not pulled:
            return False

        logging.info('Waiting for Pepper process.')
        # Verify that we see a ppapi process and assume it is Flash.
        ppapi = utils.wait_for_value_changed(
            lambda: (utils.get_process_list('chrome', '--type=ppapi')),
            old_value=[],
            timeout_sec=5)
        logging.info('ppapi process list at start: %s', ', '.join(ppapi))
        if not ppapi:
            msg = 'flash/platform/pepper/pep_'
            if not self._ui_log_reader.can_find(msg):
                raise error.TestFail(
                    'Flash did not start (logs) and no ppapi process found.')
            # There is a chrome bug where the command line of the ppapi and
            # other processes is shown as "type=zygote". Bail out if we see more
            # than 2. Notice, we already did the waiting, so there is no need to
            # do more of it.
            zygote = utils.get_process_list('chrome', '--type=zygote')
            if len(zygote) > 2:
                logging.warning(
                    'Flash probably launched by Chrome as zygote: '
                    '<%s>.', ', '.join(zygote))
                return False

        # We have a ppapi process. Let it run for a little and see if it is
        # still alive.
        logging.info('Running Flash content for a little while.')
        time.sleep(5)
        logging.info('Verifying the Pepper process is still around.')
        ppapi = utils.wait_for_value_changed(
            lambda: (utils.get_process_list('chrome', '--type=ppapi')),
            old_value=[],
            timeout_sec=3)
        # Notice that we are not checking for equality of ppapi on purpose.
        logging.info('PPapi process list found: <%s>', ', '.join(ppapi))

        # Any better pattern matching?
        msg = ' Received crash notification for ' + constants.BROWSER
        if self._messages_log_reader.can_find(msg):
            raise error.TestFail('Browser crashed during test.')

        if not ppapi:
            raise error.TestFail('Pepper process disappeared during test.')

        # At a minimum Flash identifies itself during process start.
        msg = 'flash/platform/pepper/pep_'
        if not self._ui_log_reader.can_find(msg):
            raise error.TestFail('Saw ppapi process but no Flash output.')

        return True
Ejemplo n.º 10
0
    def run_once(self,
                 host,
                 test_mirrored=False,
                 test_suspend_resume=False,
                 test_reboot=False,
                 test_lid_close_open=False,
                 resolution_list=None):

        # Check the servo object.
        if test_lid_close_open and host.servo is None:
            raise error.TestError('Invalid servo object found on the host.')
        if test_lid_close_open and not host.get_board_type() == 'CHROMEBOOK':
            raise error.TestNAError('DUT is not Chromebook. Test Skipped')
        if test_mirrored and not host.get_board_type() == 'CHROMEBOOK':
            raise error.TestNAError('DUT is not Chromebook. Test Skipped')

        # Check for incompatible with servo chromebooks.
        board_name = host.get_board().split(':')[1]
        if board_name in self.INCOMPATIBLE_SERVO_BOARDS:
            raise error.TestNAError(
                'DUT is incompatible with servo. Skipping test.')

        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.setup_and_reset(self.outputdir)
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
            chameleon_board, display_facade)

        errors = []
        if resolution_list is None:
            resolution_list = self.DEFAULT_RESOLUTION_LIST
        chameleon_supported = True
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                host, chameleon_port, display_facade, self.outputdir)
            chameleon_port_name = chameleon_port.get_connector_type()
            logging.info('Detected %s chameleon port.', chameleon_port_name)
            for label, width, height in resolution_list:
                test_resolution = (width, height)
                test_name = "%s_%dx%d" % ((label, ) + test_resolution)

                # The chameleon DP RX doesn't support 4K resolution.
                # The max supported resolution is 2560x1600.
                # See crbug/585900
                if (chameleon_port_name.startswith('DP') and test_resolution >
                    (2560, 1600)):
                    chameleon_supported = False

                if not edid.is_edid_supported(host, width, height):
                    logging.info('Skip unsupported EDID: %s', test_name)
                    continue

                if test_lid_close_open:
                    logging.info('Close lid...')
                    host.servo.lid_close()
                    time.sleep(self.WAIT_TIME_LID_TRANSITION)

                if test_reboot:
                    # Unplug the monitor explicitly. Otherwise, the following
                    # use_edid_file() call would expect a valid video signal,
                    # which is not true during reboot.
                    chameleon_port.unplug()
                    logging.info('Reboot...')
                    boot_id = host.get_boot_id()
                    host.reboot(wait=False)
                    host.test_wait_for_shutdown(self.REBOOT_TIMEOUT)

                path = os.path.join(self.bindir, 'test_data', 'edids',
                                    test_name)
                logging.info('Use EDID: %s', test_name)
                with chameleon_port.use_edid_file(path):
                    if test_lid_close_open:
                        logging.info('Open lid...')
                        host.servo.lid_open()
                        time.sleep(self.WAIT_TIME_LID_TRANSITION)

                    if test_reboot:
                        host.test_wait_for_boot(boot_id)
                        chameleon_port.plug()

                    utils.wait_for_value_changed(
                        display_facade.get_external_connector_name,
                        old_value=False)

                    logging.info('Set mirrored: %s', test_mirrored)
                    display_facade.set_mirrored(test_mirrored)
                    if test_suspend_resume:
                        if test_mirrored:
                            # magic sleep to wake up nyan_big in mirrored mode
                            # TODO: find root cause
                            time.sleep(6)
                        logging.info('Going to suspend...')
                        display_facade.suspend_resume()
                        logging.info('Resumed back')

                    screen_test.test_screen_with_image(test_resolution,
                                                       test_mirrored, errors,
                                                       chameleon_supported)

        if errors:
            raise error.TestFail('; '.join(set(errors)))
Ejemplo n.º 11
0
    def run_once(self, host, test_mirrored=False):
        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.reset()
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
                chameleon_board, display_facade)

        errors = []
        warns = []
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                    chameleon_port, display_facade, self.outputdir)

            logging.info('See the display on Chameleon: port %d (%s)',
                         chameleon_port.get_connector_id(),
                         chameleon_port.get_connector_type())

            logging.info('Set mirrored: %s', test_mirrored)
            display_facade.set_mirrored(test_mirrored)

            # Keep the original connector name, for later comparison.
            expected_connector = display_facade.get_external_connector_name()
            resolution = display_facade.get_external_resolution()
            logging.info('See the display on DUT: %s %r',
                         expected_connector, resolution)

            for (plugged_before_noise,
                 plugged_after_noise) in self.PLUG_CONFIGS:
                logging.info('TESTING THE CASE: %s > noise > %s',
                             'plug' if plugged_before_noise else 'unplug',
                             'plug' if plugged_after_noise else 'unplug')

                chameleon_port.set_plug(plugged_before_noise)

                if screen_test.check_external_display_connected(
                        expected_connector if plugged_before_noise else False,
                        errors):
                    # Skip the following test if an unexpected display detected.
                    continue

                chameleon_port.fire_mixed_hpd_pulses(
                        self.PULSES_PLUGGED if plugged_after_noise
                                            else self.PULSES_UNPLUGGED)

                if plugged_after_noise:
                    chameleon_port.wait_video_input_stable()
                    if test_mirrored:
                        # Wait for resolution change to make sure the resolution
                        # is stable before moving on. This is to deal with the
                        # case where DUT may respond slowly after the noise.
                        # If the resolution doesn't change, then we are
                        # confident that it is stable. Otherwise, a slow
                        # response is caught.
                        r = display_facade.get_internal_resolution()
                        utils.wait_for_value_changed(
                                display_facade.get_internal_resolution,
                                old_value=r)

                    err = screen_test.check_external_display_connected(
                            expected_connector)

                    if not err:
                        err = screen_test.test_screen_with_image(
                                resolution, test_mirrored)
                    if err:
                        # When something goes wrong after the noise, a normal
                        # user would try to re-plug the cable to recover.
                        # We emulate this behavior below and report error if
                        # the problem persists.
                        logging.warn('Possibly flaky: %s', err)
                        warns.append('Possibly flaky: %s' % err)
                        logging.info('Replug and retry the screen test...')
                        chameleon_port.unplug()
                        time.sleep(self.REPLUG_DELAY_SEC)
                        chameleon_port.plug()
                        chameleon_port.wait_video_input_stable()
                        screen_test.test_screen_with_image(
                                resolution, test_mirrored, errors)
                else:
                    screen_test.check_external_display_connected(False, errors)
                    time.sleep(1)

        if errors:
            raise error.TestFail('; '.join(set(errors)))
        elif warns:
            raise error.TestWarn('; '.join(set(warns)))
Ejemplo n.º 12
0
    def _yield_all_ports(self, failed_ports=None, raise_error=False):
        """
        Yields all connected video ports and ensures every of them plugged.

        @param failed_ports: A list to append the failed port or None.
        @param raise_error: True to raise TestFail if no connected video port.
        @yields every connected ChameleonVideoInput which is ensured plugged
                before yielding.

        @raises TestFail if raise_error is True and no connected video port.

        """
        yielded = False
        all_ports = super(ChameleonVideoInputFinder, self).find_all_ports()

        # unplug all ports
        for port in all_ports.connected:
            if port.has_video_support():
                chameleon.ChameleonVideoInput(port).unplug()
                self.display_facade.reset_connector_if_applicable(
                    port.get_connector_type())

        for port in all_ports.connected:
            # Skip the non-video port.
            if not port.has_video_support():
                continue

            video_port = chameleon.ChameleonVideoInput(port)
            # Plug the port to make it visible.
            video_port.plug()
            try:
                # DUT takes some time to respond. Wait until the video signal
                # to stabilize and wait for the connector change.
                video_stable = video_port.wait_video_input_stable(
                    self._TIMEOUT_VIDEO_STABLE_PROBE)
                output = utils.wait_for_value_changed(
                    self.display_facade.get_external_connector_name,
                    old_value=False)

                if not output:
                    logging.warn(
                        'Maybe flaky that no display detected. Retry.')
                    video_port.unplug()
                    time.sleep(self.REPLUG_DELAY_SEC)
                    video_port.plug()
                    video_stable = video_port.wait_video_input_stable(
                        self._TIMEOUT_VIDEO_STABLE_PROBE)
                    output = utils.wait_for_value_changed(
                        self.display_facade.get_external_connector_name,
                        old_value=False)

                logging.info('CrOS detected external connector: %r', output)

                if output:
                    yield video_port
                    yielded = True
                else:
                    if failed_ports is not None:
                        failed_ports.append(video_port)
                    logging.error('CrOS failed to see any external display')
                    if not video_stable:
                        logging.warn('Chameleon timed out waiting CrOS video')
            finally:
                # Unplug the port not to interfere with other tests.
                video_port.unplug()

        if raise_error and not yielded:
            raise error.TestFail('No connected video port found between CrOS '
                                 'and Chameleon.')
Ejemplo n.º 13
0
    def run_once(self,
                 host,
                 test_mirrored=False,
                 test_suspend_resume=False,
                 test_reboot=False,
                 test_lid_close_open=False,
                 resolution_list=None):
        # Check the servo object
        if test_lid_close_open and host.servo is None:
            raise error.TestError('Invalid servo object found on the host.')
        if test_lid_close_open and not host.get_board_type() == 'CHROMEBOOK':
            raise error.TestNAError('DUT is not Chromebook. Test Skipped')

        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.reset()
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
            chameleon_board, display_facade)

        errors = []
        if resolution_list is None:
            resolution_list = self.DEFAULT_RESOLUTION_LIST
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                chameleon_port, display_facade, self.outputdir)
            chameleon_port_name = chameleon_port.get_connector_type()
            logging.info('Detected %s chameleon port.', chameleon_port_name)
            for interface, width, height in resolution_list:
                if not chameleon_port_name.startswith(interface):
                    continue
                test_resolution = (width, height)
                test_name = "%s_%dx%d" % ((interface, ) + test_resolution)

                if not edid.is_edid_supported(host, interface, width, height):
                    logging.info('Skip unsupported EDID: %s', test_name)
                    continue

                if test_lid_close_open:
                    logging.info('Close lid...')
                    host.servo.lid_close()
                    time.sleep(self.WAIT_TIME_LID_TRANSITION)

                if test_reboot:
                    logging.info('Reboot...')
                    boot_id = host.get_boot_id()
                    host.reboot(wait=False)
                    host.test_wait_for_shutdown(self.REBOOT_TIMEOUT)

                path = os.path.join(self.bindir, 'test_data', 'edids',
                                    test_name)
                logging.info('Use EDID: %s', test_name)
                with chameleon_port.use_edid_file(path):
                    if test_lid_close_open:
                        logging.info('Open lid...')
                        host.servo.lid_open()
                        time.sleep(self.WAIT_TIME_LID_TRANSITION)

                    if test_reboot:
                        host.test_wait_for_boot(boot_id)

                    utils.wait_for_value_changed(
                        display_facade.get_external_connector_name,
                        old_value=False)

                    logging.info('Set mirrored: %s', test_mirrored)
                    display_facade.set_mirrored(test_mirrored)
                    if test_suspend_resume:
                        if test_mirrored:
                            # magic sleep to wake up nyan_big in mirrored mode
                            # TODO: find root cause
                            time.sleep(6)
                        logging.info('Going to suspend...')
                        display_facade.suspend_resume()
                        logging.info('Resumed back')

                    screen_test.test_screen_with_image(test_resolution,
                                                       test_mirrored, errors)

        if errors:
            raise error.TestFail('; '.join(set(errors)))
    def verify_flash_process(self, load_path=None):
        """Verifies the Flash process runs and doesn't crash.

        @param load_path: The expected path of the Flash binary. If set
                          function and Flash was loaded from a different path,
                          function will fail the test.
        """
        logging.info('Waiting for Pepper process.')
        # Verify that we see a ppapi process and assume it is Flash.
        ppapi = utils.wait_for_value_changed(
            lambda: (utils.get_process_list('chrome', '--type=ppapi')),
            old_value=[],
            timeout_sec=self._time_to_wait_secs)
        logging.info('ppapi process list at start: %s', ', '.join(ppapi))
        if not ppapi:
            msg = 'flash/platform/pepper/pep_'
            if not self._ui_log_reader.can_find(msg):
                raise error.TestFail(
                    'Failed: Flash did not start (logs) and no ppapi process '
                    'found.')
            # There is a chrome bug where the command line of the ppapi and
            # other processes is shown as "type=zygote". Bail out if we see more
            # than 2. Notice, we already did the waiting, so there is no need to
            # do more of it.
            zygote = utils.get_process_list('chrome', '--type=zygote')
            if len(zygote) > 2:
                logging.warning(
                    'Flash probably launched by Chrome as zygote: '
                    '<%s>.', ', '.join(zygote))

        # We have a ppapi process. Let it run for a little and see if it is
        # still alive.
        logging.info('Running Flash content for a little while.')
        time.sleep(self._swf_runtime)
        logging.info('Verifying the Pepper process is still around.')
        ppapi = utils.wait_for_value_changed(
            lambda: (utils.get_process_list('chrome', '--type=ppapi')),
            old_value=[],
            timeout_sec=self._time_to_wait_secs)
        # Notice that we are not checking for equality of ppapi on purpose.
        logging.info('PPapi process list found: <%s>', ', '.join(ppapi))

        # Any better pattern matching?
        msg = ' Received crash notification for ' + constants.BROWSER
        if self._messages_log_reader.can_find(msg):
            raise error.TestFail('Failed: Browser crashed during test.')
        if not ppapi:
            raise error.TestFail(
                'Failed: Pepper process disappeared during test.')

        # At a minimum Flash identifies itself during process start.
        msg = 'flash/platform/pepper/pep_'
        if not self._ui_log_reader.can_find(msg):
            raise error.TestFail(
                'Failed: Saw ppapi process but no Flash output.')

        # Check that libpepflashplayer.so was loaded from the expected path.
        if load_path:
            # Check all current process for Flash library.
            output = subprocess.check_output(
                ['grep libpepflashplayer.so /proc/*/maps'], shell=True)
            # Verify there was no other than the expected location.
            for dont_load_path in _FLASH_PATHS - {load_path}:
                if dont_load_path in output:
                    logging.error('Flash incorrectly loaded from %s',
                                  dont_load_path)
                    logging.info(output)
                    raise error.TestFail('Failed: Flash incorrectly loaded '
                                         'from %s' % dont_load_path)
                logging.info('Verified Flash was indeed not loaded from %s',
                             dont_load_path)
            # Verify at least one of the libraries came from where we expected.
            if not load_path in output:
                # Mystery. We saw a Flash loaded from who knows where.
                logging.error('Flash not loaded from %s', load_path)
                logging.info(output)
                raise error.TestFail('Failed: Flash not loaded from %s' %
                                     load_path)
            logging.info('Saw a flash library loaded from %s.', load_path)