def start_dut_ping_process(self, iperf_server_on_ap, ip_version=IPV4):
        """Creates a  process that pings the AP from the DUT.

        Runs in parallel for 15 seconds, so it can be interrupted by a reboot.
        Sleeps for a few seconds to ensure pings have started.

        Args:
            iperf_server_on_ap: IPerfServer object, linked to AP
            ip_version: string, the ip version (ipv4 or ipv6)
        """
        ap_address = self.get_iperf_server_address(iperf_server_on_ap,
                                                   ip_version)
        if ap_address:
            self.log.info(
                'Starting ping process to %s in parallel. Logs from this '
                'process will be suppressed, since it will be intentionally '
                'interrupted.' % ap_address)
            ping_proc = Process(target=self.dut.ping,
                                args=[ap_address],
                                kwargs={'count': 15})
            with utils.SuppressLogOutput():
                ping_proc.start()
            # Allow for a few seconds of pinging before allowing it to be
            # interrupted.
            time.sleep(3)
        else:
            raise ConnectionError('Failed to retrieve APs iperf address.')
Пример #2
0
    def import_test_modules(self, test_paths):
        """Imports test classes from test scripts.

        1. Locate all .py files under test paths.
        2. Import the .py files as modules.
        3. Find the module members that are test classes.
        4. Categorize the test classes by name.

        Args:
            test_paths: A list of directory paths where the test files reside.

        Returns:
            A dictionary where keys are test class name strings, values are
            actual test classes that can be instantiated.
        """
        def is_testfile_name(name, ext):
            if ext == '.py':
                if name.endswith('Test') or name.endswith('_test'):
                    return True
            return False

        file_list = utils.find_files(test_paths, is_testfile_name)
        test_classes = {}
        for path, name, _ in file_list:
            sys.path.append(path)
            try:
                with utils.SuppressLogOutput(
                        log_levels=[logging.INFO, logging.ERROR]):
                    module = importlib.import_module(name)
            except Exception as e:
                logging.debug('Failed to import %s: %s', path, str(e))
                for test_cls_name, _ in self.run_list:
                    alt_name = name.replace('_', '').lower()
                    alt_cls_name = test_cls_name.lower()
                    # Only block if a test class on the run list causes an
                    # import error. We need to check against both naming
                    # conventions: AaaBbb and aaa_bbb.
                    if name == test_cls_name or alt_name == alt_cls_name:
                        msg = ('Encountered error importing test class %s, '
                               'abort.') % test_cls_name
                        # This exception is logged here to help with debugging
                        # under py2, because "raise X from Y" syntax is only
                        # supported under py3.
                        self.log.exception(msg)
                        raise ValueError(msg)
                continue
            for member_name in dir(module):
                if not member_name.startswith('__'):
                    if member_name.endswith('Test'):
                        test_class = getattr(module, member_name)
                        if inspect.isclass(test_class):
                            test_classes[member_name] = test_class
        return test_classes
Пример #3
0
 def test_suppress_log_output(self):
     """Tests that the SuppressLogOutput context manager removes handlers
     of the specified levels upon entry and re-adds handlers upon exit.
     """
     handlers = [
         logging.NullHandler(level=lvl)
         for lvl in (logging.DEBUG, logging.INFO, logging.ERROR)
     ]
     log = logging.getLogger('test_log')
     for handler in handlers:
         log.addHandler(handler)
     with utils.SuppressLogOutput(log, [logging.INFO, logging.ERROR]):
         self.assertTrue(
             any(handler.level == logging.DEBUG
                 for handler in log.handlers))
         self.assertFalse(
             any(handler.level in (logging.INFO, logging.ERROR)
                 for handler in log.handlers))
     self.assertCountEqual(handlers, log.handlers)
    def reboot(self,
               use_ssh=False,
               unreachable_timeout=30,
               ping_timeout=30,
               ssh_timeout=30,
               reboot_type=FUCHSIA_REBOOT_TYPE_SOFT,
               testbed_pdus=None):
        """Reboot a FuchsiaDevice.

        Soft reboots the device, verifies it becomes unreachable, then verfifies
        it comes back online. Reinitializes SL4F so the tests can continue.

        Args:
            use_ssh: bool, if True, use fuchsia shell command via ssh to reboot
                instead of SL4F.
            unreachable_timeout: int, time to wait for device to become
                unreachable.
            ping_timeout: int, time to wait for device to respond to pings.
            ssh_timeout: int, time to wait for device to be reachable via ssh.
            reboot_type: boolFUCHSIA_REBOOT_TYPE_SOFT or
                FUCHSIA_REBOOT_TYPE_HARD
            testbed_pdus: list, all testbed PDUs

        Raises:
            ConnectionError, if device fails to become unreachable, fails to
                come back up, or if SL4F does not setup correctly.
        """
        # Call Reboot
        if reboot_type == FUCHSIA_REBOOT_TYPE_SOFT:
            if use_ssh:
                self.log.info('Sending reboot command via SSH.')
                with utils.SuppressLogOutput():
                    self.clean_up()
                    self.send_command_ssh(
                        'dm reboot',
                        timeout=FUCHSIA_RECONNECT_AFTER_REBOOT_TIME,
                        skip_status_code_check=True)
            else:
                self.log.info('Initializing reboot of FuchsiaDevice (%s)'
                              ' with SL4F.' % self.ip)
                self.log.info('Calling SL4F reboot command.')
                with utils.SuppressLogOutput():
                    if self.log_process:
                        self.log_process.stop()
                    self.hardware_power_statecontrol_lib.suspendReboot(
                        timeout=3)
                    if self._persistent_ssh_conn:
                        self._persistent_ssh_conn.close()
                        self._persistent_ssh_conn = None
        elif reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
            self.log.info('Power cycling FuchsiaDevice (%s)' % self.ip)
            device_pdu, device_pdu_port = pdu.get_pdu_port_for_device(
                self.device_pdu_config, testbed_pdus)
            with utils.SuppressLogOutput():
                if self.log_process:
                    self.log_process.stop()
                if self._persistent_ssh_conn:
                    self._persistent_ssh_conn.close()
                    self._persistent_ssh_conn = None
            self.log.info('Killing power to FuchsiaDevice (%s)...' % self.ip)
            device_pdu.off(str(device_pdu_port))

        # Wait for unreachable
        self.log.info('Verifying device is unreachable.')
        timeout = time.time() + unreachable_timeout
        while (time.time() < timeout):
            if utils.is_pingable(self.ip):
                self.log.debug('Device is still pingable. Retrying.')
            else:
                if reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
                    self.log.info('Restoring power to FuchsiaDevice (%s)...' %
                                  self.ip)
                    device_pdu.on(str(device_pdu_port))
                break
        else:
            self.log.info('Device failed to go offline. Reintializing Sl4F.')
            self.start_services()
            self.init_server_connection()
            raise ConnectionError('Device never went down.')
        self.log.info('Device is unreachable as expected.')

        if reboot_type == FUCHSIA_REBOOT_TYPE_HARD:
            self.log.info('Restoring power to FuchsiaDevice (%s)...' % self.ip)
            device_pdu.on(str(device_pdu_port))

        self.log.info('Waiting for device to respond to pings.')
        self.verify_ping(timeout=ping_timeout)
        self.log.info('Device responded to pings.')

        self.log.info('Waiting for device to allow ssh connection.')
        self.verify_ssh(timeout=ssh_timeout)
        self.log.info('Device now available via ssh.')

        # Creating new log process, start it, start new persistent ssh session,
        # start SL4F, and connect via SL4F
        self.log.info(
            'Restarting log process and reinitiating SL4F on FuchsiaDevice %s'
            % self.ip)
        self.log_process.start()
        self.start_services()

        # Verify SL4F is up.
        self.log.info(
            'Initiating connection to SL4F and verifying commands can run.')
        try:
            self.init_server_connection()
            self.hwinfo_lib.getDeviceInfo()
        except Exception as err:
            raise ConnectionError(
                'Failed to connect and run command via SL4F. Err: %s' % err)
        self.log.info(
            'Device has rebooted, SL4F is reconnected and functional.')
Пример #5
0
    def _run_traffic(self,
                     uuid,
                     client,
                     server_ip,
                     server_port,
                     active_streams,
                     stream_results,
                     access_category=None,
                     bandwidth=None,
                     stream_time=DEFAULT_STREAM_TIME,
                     start_time=None):
        """Runs an iperf3 stream.

        1. Adds stream UUID to active_streams
        2. Runs stream
        3. Saves results to stream_results
        4. Removes stream UUID from active_streams

        Args:
            uuid: UUID object, identifier for stream
            client: IPerfClient object on device
            server_ip: string, ip address of IPerfServer for stream
            server_port: int, port of the IPerfServer for stream
            active_streams: multiprocessing.Manager.dict, which holds stream
                UUIDs of active streams on the device
            stream_results: multiprocessing.Manager.dict, which maps stream
                UUIDs of streams to IPerfResult objects
            access_category: string, WMM access category to use with iperf
                (AC_BK, AC_BE, AC_VI, AC_VO). Unset if None.
            bandwidth: int, bandwidth in mbps to use with iperf. Implies UDP.
                Unlimited if None.
            stream_time: int, time in seconds, to run iperf stream
            start_time: float, time, seconds since epoch, at which to start the
                stream (for better synchronicity). If None, start immediately.
        """
        active_streams[uuid] = True
        # SSH sessions must be started within the process that is going to
        # use it.
        if type(client) == iperf_client.IPerfClientOverSsh:
            with utils.SuppressLogOutput():
                client.start_ssh()

        ac_flag = ''
        bandwidth_flag = ''
        time_flag = '-t %s' % stream_time

        if access_category:
            ac_flag = ' -S %s' % DEFAULT_AC_TO_TOS_TAG_MAP[access_category]

        if bandwidth:
            bandwidth_flag = ' -u -b %sM' % bandwidth

        iperf_flags = '-p %s -i 1 %s%s%s -J' % (server_port, time_flag,
                                                ac_flag, bandwidth_flag)
        if not start_time:
            start_time = time.time()
        time_str = datetime.fromtimestamp(start_time).strftime('%H:%M:%S.%f')
        self.log.info(
            'At %s, starting %s second stream to %s:%s with (AC: %s, Bandwidth: %s)'
            % (time_str, stream_time, server_ip, server_port, access_category,
               bandwidth if bandwidth else 'Unlimited'))

        # If present, wait for stream start time
        if start_time:
            current_time = time.time()
            while current_time < start_time:
                current_time = time.time()
        path = client.start(server_ip, iperf_flags, '%s' % uuid)
        stream_results[uuid] = iperf_server.IPerfResult(
            path, reporting_speed_units='mbps')

        if type(client) == iperf_client.IPerfClientOverSsh:
            client.close_ssh()
        active_streams.pop(uuid)