Exemplo n.º 1
0
def _click_start_button(driver, errors):
    """Clicks the "Start Test" button in the web UI.

    Args:
        driver: An instance of a Selenium webdriver browser class.
        errors: An errors list.

    Returns:
        True if the "Start Test" button could be successfully located
        and clicked.
    """
    start_button = browser_client_common.find_element_containing_text(
        driver, 'Start Test')
    if not start_button:
        errors.append(results.TestError(ERROR_START_BUTTON_NOT_IN_DOM))
        logger.error(ERROR_START_BUTTON_NOT_IN_DOM)
        return False
    if not browser_client_common.wait_until_element_is_visible(
            driver, start_button, browser_client_common.UI_WAIT_TIMEOUT):
        errors.append(
            results.TestError(ERROR_TIMED_OUT_WAITING_FOR_START_BUTTON))
        logger.error(ERROR_TIMED_OUT_WAITING_FOR_START_BUTTON)
        return False
    start_button.click()
    return True
Exemplo n.º 2
0
def _complete_ui_flow(driver, url, result):
    """Performs the UI flow for the NDT HTML5 test and records results.

    Args:
        driver: An instance of a Selenium webdriver browser class.
        url: URL to load to start the UI flow.
        result: NdtResult instance to populate with results from proceeding
            through the UI flow.
    """
    logger.info('loading URL: %s', url)
    if not browser_client_common.load_url(driver, url, result.errors):
        return
    logger.info('page loaded, starting UI flow')

    _click_websocket_button(driver)
    # If we can't click the start button, nothing left to do, so bail out.
    if not _click_start_button(driver, result.errors):
        return
    logger.info('clicked "Start Test" button')
    result.c2s_result = results.NdtSingleTestResult()
    result.s2c_result = results.NdtSingleTestResult()

    if _wait_for_c2s_test_to_start(driver):
        result.c2s_result.start_time = datetime.datetime.now(pytz.utc)
        logger.info('c2s test started')
    else:
        result.errors.append(
            results.TestError(browser_client_common.ERROR_C2S_NEVER_STARTED))
        logger.error(browser_client_common.ERROR_C2S_NEVER_STARTED)

    if _wait_for_s2c_test_to_start(driver):
        result.c2s_result.end_time = datetime.datetime.now(pytz.utc)
        logger.info('c2s test finished')
        result.s2c_result.start_time = datetime.datetime.now(pytz.utc)
        logger.info('s2c test started')
    else:
        result.errors.append(
            results.TestError(browser_client_common.ERROR_S2C_NEVER_STARTED))
        logger.error(browser_client_common.ERROR_S2C_NEVER_STARTED)

    if _wait_for_results_page_to_appear(driver):
        result.s2c_result.end_time = datetime.datetime.now(pytz.utc)
        logger.info('s2c test finished')
    else:
        result.errors.append(
            results.TestError(browser_client_common.ERROR_S2C_NEVER_ENDED))
        logger.error(browser_client_common.ERROR_S2C_NEVER_ENDED)

    _populate_metric_values(result, driver)
Exemplo n.º 3
0
def _parse_throughput(errors, throughput, throughput_units,
                      throughput_metric_name):
    """Converts metric into a valid numeric value in Mb/s .

    For a given metric, checks that it is a valid numeric value. If not, an
    error is added to the list contained in the NdtResult instance attribute.
    If it is, it is converted into Mb/s where necessary.

    Args:
        errors: An errors list.
        throughput: The throughput value that is to be evaluated.
        throughput_units: The units for the throughput value that is to be
        evaluated (one of kb/s, Mb/s, Gb/s).
        throughput_metric_name: A string representing the name of the throughput
        metric to validate.

    Returns:
        float representing the converted metric, None if an illegal value
            is given.
    """
    if _convert_metric_to_float(errors, throughput, throughput_metric_name):
        throughput = float(throughput)
        if throughput_units == 'kb/s':
            converted_throughput = throughput / 1000
            return converted_throughput
        elif throughput_units == 'Gb/s':
            converted_throughput = throughput * 1000
            return converted_throughput
        elif throughput_units == 'Mb/s':
            return throughput
        else:
            errors.append(
                results.TestError('Invalid throughput unit specified: %s' %
                                  throughput_units))
    return None
def load_url(driver, url, errors):
    """Loads the URL in a Selenium driver for an NDT test.

    Args:
        driver: An instance of a Selenium webdriver.
        url: The URL to load.
        errors: A list of errors that will be appended to if the URL cannot be
            loaded.

    Returns:
        True if loading the URL was successful.
    """
    try:
        driver.get(url)
    except (exceptions.WebDriverException, exceptions.TimeoutException) as e:
        if type(e) is exceptions.TimeoutException:
            errors.append(
                results.TestError(ERROR_TIMED_OUT_WAITING_FOR_PAGE_LOAD))
        errors.append(results.TestError(ERROR_FAILED_TO_LOAD_URL_FORMAT % url))
        return False
    return True
def _load_url(driver, url, result):
    """Loads the URL in a Selenium driver for an NDT test.

    Args:
        driver: An instance of a Selenium webdriver.
        url: The The URL of an NDT server to test against.
        result: An instance of NdtResult.

    Returns:
        True if loading the URL was successful, False if otherwise.
    """
    try:
        driver.get(url)
    except exceptions.WebDriverException:
        result.errors.append(results.TestError('Failed to load test UI.'))
        return False
    return True
Exemplo n.º 6
0
def _record_test_in_progress_values(result, driver, timeout):
    """Records values that are measured while the NDT test is in progress.

    Measures s2c_start_time, c2s_end_time, and end_time, which are stored in
    an instance of NdtResult. These times are measured while the NDT test is
    in progress.

    Args:
        result: An instance of NdtResult.
        driver: An instance of a Selenium webdriver browser class.
        timeout: The number of seconds that the driver will wait for
            each element to become visible before timing out.

    Returns:
        True if recording the measured values was successful, False if otherwise.
    """
    try:
        # wait until 'Now Testing your upload speed' is displayed
        upload_speed_text = driver.find_elements_by_xpath(
            "//*[contains(text(), 'your upload speed')]")[0]
        result.c2s_result = results.NdtSingleTestResult()
        result.c2s_result.start_time = _record_time_when_element_displayed(
            upload_speed_text, driver, timeout=timeout)
        result.c2s_result.end_time = datetime.datetime.now(pytz.utc)

        # wait until 'Now Testing your download speed' is displayed
        download_speed_text = driver.find_elements_by_xpath(
            "//*[contains(text(), 'your download speed')]")[0]
        result.s2c_result = results.NdtSingleTestResult()
        result.s2c_result.start_time = _record_time_when_element_displayed(
            download_speed_text, driver, timeout=timeout)

        # wait until the results page appears
        results_text = driver.find_element_by_id('results')
        result.s2c_result.end_time = datetime.datetime.now(pytz.utc)
        result.end_time = _record_time_when_element_displayed(results_text,
                                                              driver,
                                                              timeout=timeout)
    except exceptions.TimeoutException:
        message = 'Test did not complete within timeout period.'
        result.errors.append(
            results.TestError(datetime.datetime.now(pytz.utc), message))
        return False
    return True
Exemplo n.º 7
0
def _populate_metric_values(result, driver):
    """Populates NdtResult with metrics from page, checks values are valid.

    Populates the NdtResult instance with metrics from the NDT test page. Checks
    thatthe values for upload (c2s) throughput, download (s2c) throughput, and
    latency within the NdtResult instance dict are valid.

    Args:
        result: An instance of NdtResult.
        driver: An instance of a Selenium webdriver browser class.

    Returns:
        True if populating metrics and checking their values was successful.
            False if otherwise.
    """
    try:
        c2s_throughput = driver.find_element_by_id('upload-speed').text
        c2s_throughput_units = driver.find_element_by_id(
            'upload-speed-units').text

        result.c2s_result.throughput = _parse_throughput(
            result.errors, c2s_throughput, c2s_throughput_units,
            'c2s throughput')

        s2c_throughput = driver.find_element_by_id('download-speed').text

        s2c_throughput_units = driver.find_element_by_id(
            'download-speed-units').text
        result.s2c_result.throughput = _parse_throughput(
            result.errors, s2c_throughput, s2c_throughput_units,
            's2c throughput')

        result.latency = driver.find_element_by_id('latency').text
        result.latency = _validate_metric(result.errors, result.latency,
                                          'latency')
    except exceptions.TimeoutException:
        message = 'Test did not complete within timeout period.'
        result.errors.append(
            results.TestError(datetime.datetime.now(pytz.utc), message))
        return False
    return True
def _convert_metric_to_float(errors, metric, metric_name):
    """Converts a given metric to a float, otherwise, adds an error object.

    If a given metric can be converted to a float, it is converted. Otherwise,
    a TestError object is added to errors.

    Args:
        errors: An errors list.
        metric: The value of the metric that is to be evaluated.
        metric_name: A string representing the name of the metric to validate.

    Returns:
        True if the validation was successful.
    """

    try:
        float(metric)
    except ValueError:
        errors.append(
            results.TestError('illegal value shown for %s: %s' %
                              (metric_name, metric)))
        return False
    return True
def _decode_error(error):
    """Decodes a dictionary into a TestError instance."""
    return results.TestError(error['message'],
                             _decode_time(error['timestamp']))
Exemplo n.º 10
0
 def _add_test_error(self, error_message):
     self._result.errors.append(results.TestError(error_message))
     logger.error(error_message)