def abstract_test_chargeback_cost(
        rate_key, obj_type, interval, chargeback_report_data, compute_rate, soft_assert):
    """This is an abstract test function for testing rate costs.
    It's comparing the expected value that calculated by the rate
    to the value in the chargeback report
    Args:
        :py:type:`str` rate_key: The rate key as it appear in the CHARGEBACK_HEADER_NAMES keys.
        :py:type:`str` obj_type: Object being tested; only 'Project' and 'Image' are supported
        :py:type:`str` interval:  The rate interval, (Hourly/Daily/Weekly/Monthly)
        :py:class:`Report` chargeback_report_data: The chargeback report data.
        :py:class:`ComputeRate` compute_rate: The compute rate object.
        :var soft_assert: soft_assert fixture.
    """
    report_headers = CHARGEBACK_HEADER_NAMES[rate_key]

    found_something_to_test = False
    for row in chargeback_report_data.rows:

        if row['Chargeback Rates'].lower() != compute_rate.description.lower():
            continue
        found_something_to_test = True

        fixed_rate = float(compute_rate.fields[report_headers.rate_name]['fixed_rate'])
        variable_rate = float(compute_rate.fields[report_headers.rate_name].get('variable_rate', 0))
        # Calculate numerical metric
        if rate_key == 'Memory':
            size_, unit_ = tokenize(row[report_headers.metric_name].upper())
            metric = round(parse_size(str(size_) + unit_, binary=True) / 1048576.0, 2)
        else:
            metric = parse_number(row[report_headers.metric_name])
        # Calculate fixed product and cost
        num_hours = parse_number(row[CHARGEBACK_HEADER_NAMES['Fixed1'].metric_name])
        num_intervals = num_hours / hours_count_lut[interval]
        fixed_cost = num_intervals * fixed_rate
        variable_cost = num_intervals * metric * variable_rate
        # Calculate expected cost
        expected_cost = round(variable_cost + fixed_cost, 2)
        found_cost = round(parse_number(row[report_headers.cost_name]), 2)

        match_threshold = TEST_MATCH_ACCURACY * expected_cost
        soft_assert(
            abs(found_cost - expected_cost) <= match_threshold,
            'Unexpected Chargeback: {}'.format(dump_args(
                charge_for=obj_type, rate_key=rate_key, metric=metric, num_hours=num_hours,
                num_intervals=num_intervals, fixed_rate=fixed_rate, variable_rate=variable_rate,
                fixed_cost=fixed_cost, variable_cost=variable_cost,
                expected_full_cost=expected_cost, found_full_cost=found_cost
            ))
        )

    assert found_something_to_test, \
        'Could not find {} with the assigned rate: {}'.format(obj_type, compute_rate.description)
예제 #2
0
def abstract_test_chargeback_cost(rate_key, obj_type, interval,
                                  chargeback_report_data, compute_rate,
                                  soft_assert):
    """This is an abstract test function for testing rate costs.
    It's comparing the expected value that calculated by the rate
    to the value in the chargeback report
    Args:
        :py:type:`str` rate_key: The rate key as it appear in the CHARGEBACK_HEADER_NAMES keys.
        :py:type:`str` obj_type: Object being tested; only 'Project' and 'Image' are supported
        :py:type:`str` interval:  The rate interval, (Hourly/Daily/Weekly/Monthly)
        :py:class:`Report` chargeback_report_data: The chargeback report data.
        :py:class:`ComputeRate` compute_rate: The compute rate object.
        :var soft_assert: soft_assert fixture.
    """
    report_headers = CHARGEBACK_HEADER_NAMES[rate_key]

    found_something_to_test = False
    for row in chargeback_report_data.rows:

        if row['Chargeback Rates'].lower() != compute_rate.description.lower():
            continue
        found_something_to_test = True

        fixed_rate = float(
            compute_rate.fields[report_headers.rate_name]['fixed_rate'])
        variable_rate = float(
            compute_rate.fields[report_headers.rate_name].get(
                'variable_rate', 0))
        # Calculate numerical metric
        if rate_key == 'Memory':
            size_, unit_ = tokenize(row[report_headers.metric_name].upper())
            metric = round(
                parse_size(str(size_) + unit_, binary=True) / 1048576.0, 2)
        else:
            metric = parse_number(row[report_headers.metric_name])
        # Calculate fixed product and cost
        num_hours = parse_number(
            row[CHARGEBACK_HEADER_NAMES['Fixed1'].metric_name])
        num_intervals = num_hours / hours_count_lut[interval]
        fixed_cost = num_intervals * fixed_rate
        variable_cost = num_intervals * metric * variable_rate
        # Calculate expected cost
        expected_cost = round(variable_cost + fixed_cost, 2)
        found_cost = round(parse_number(row[report_headers.cost_name]), 2)

        match_threshold = TEST_MATCH_ACCURACY * expected_cost
        soft_assert(
            abs(found_cost - expected_cost) <= match_threshold,
            'Unexpected Chargeback: {}'.format(
                dump_args(charge_for=obj_type,
                          rate_key=rate_key,
                          metric=metric,
                          num_hours=num_hours,
                          num_intervals=num_intervals,
                          fixed_rate=fixed_rate,
                          variable_rate=variable_rate,
                          fixed_cost=fixed_cost,
                          variable_cost=variable_cost,
                          expected_full_cost=expected_cost,
                          found_full_cost=found_cost)))

    assert found_something_to_test, \
        'Could not find {} with the assigned rate: {}'.format(obj_type, compute_rate.description)
예제 #3
0
def process_opts(opts):
    from .content import makedirs

    init_logging(opts)

    if opts.insecure:
        from keyrings.cryptfile.file import PlaintextKeyring
        set_keyring(PlaintextKeyring())

    if opts.username:
        log.debug('Username provided, updating in keyring')
        keyring.set_password('plexiglas', 'myplex_login', opts.username)
    else:
        log.debug('No username in args')
        opts.username = keyring.get_password('plexiglas', 'myplex_login')

        if not opts.username:
            from six.moves import input
            log.debug('No username in keyring')
            opts.username = input('Please provide MyPlex login: '******'plexiglas', 'myplex_login',
                                     opts.username)

    if not opts.username:
        log.debug('No username')
        print('MyPlex login is required')
        exit(1)

    if opts.password:
        keyring.set_password('plexiglas', opts.username, opts.password)
    else:
        opts.password = keyring.get_password('plexiglas', opts.username)

    if not opts.password:
        import getpass
        opts.password = getpass.getpass('Enter the plex.tv password for %s: ' %
                                        opts.username)
        keyring.set_password('plexiglas', opts.username, opts.password)

    opts.destination = os.path.realpath(os.path.expanduser(opts.destination))

    if not os.access(opts.destination, os.W_OK):
        try:
            makedirs(opts.destination, exist_ok=True)
        except OSError:
            print('Directory "%s" should be writable' % opts.destination)
            exit(1)

    os.chdir(opts.destination)

    if opts.limit_disk_usage:
        if '%' in opts.limit_disk_usage:
            tokens = hf.tokenize(opts.limit_disk_usage)
            if len(tokens) == 2 and tokens[1] == '%' and tokens[0] <= 100:
                from .content import get_total_disk_space

                total_space = get_total_disk_space(opts.destination)
                opts.limit_disk_usage = int(total_space / 100 * int(tokens[0]))
                log.info('Setting disk usage limit to %s',
                         hf.format_size(opts.limit_disk_usage, binary=True))
            else:
                print('Unexpected disk usage limit')
                exit(1)
        else:
            opts.limit_disk_usage = hf.parse_size(opts.limit_disk_usage,
                                                  binary=True)

    if opts.rate_limit and not opts.rate_limit.isdigit():
        opts.rate_limit = hf.parse_size(opts.rate_limit, binary=True)

    for plugin in get_all_plugins():
        if hasattr(plugin, 'process_options'):
            log.debug('Running process_options on %s', plugin.name)
            plugin.process_options(opts)