Exemple #1
0
def metric_expression_to_graph_recipe_expression(
    expression: MetricExpression,
    translated_metrics: TranslatedMetrics,
    lq_row: Row,
    enforced_consolidation_function: Optional[GraphConsoldiationFunction],
) -> StackElement:
    """Convert 'user,util,+,2,*' into this:

        ('operator',
            '*',
            [('operator',
            '+',
            [('rrd',
                'heute',
                u'heute',
                u'CPU utilization',
    ...."""
    rrd_base_element = (
        "rrd",
        lq_row["site"],
        lq_row["host_name"],
        lq_row.get("service_description", "_HOST_"),
    )

    expression = split_expression(expression)[0]
    atoms: List[RPNAtom] = []
    # Break the RPN into parts and translate each part separately
    for part, cf in iter_rpn_expression(expression,
                                        enforced_consolidation_function):
        # Some parts are operators. We leave them. We are just interested in
        # names of metrics.
        if part in translated_metrics:  # name of a variable that we know
            tme = translated_metrics[part]
            metric_names = tme.get("orig_name",
                                   [part])  # original name before translation
            # We do the replacement of special characters with _ right here.
            # Normally it should be a task of the core. But: We have variables
            # named "/" - which is very silly, but is due to the bogus perf names
            # of the df check. So the CMC could not really distinguish this from
            # the RPN operator /.
            for metric_name, scale in zip(metric_names, tme["scale"]):
                atoms.append(rrd_base_element +
                             (pnp_cleanup(metric_name), cf, scale))
            if len(metric_names) > 1:
                atoms.append(("operator", "MERGE"))

        else:
            try:
                atoms.append(("constant", float(part)))
            except ValueError:
                atoms.append(("operator", part))

    return stack_resolver(
        atoms,
        is_operator=lambda x: x[0] == "operator",
        apply_operator=lambda op, a, b: (op + ([a, b], )),
        apply_element=lambda x: x,
    )
def test_stack_resolver_exception_missing_operator_arguments():
    with pytest.raises(
            utils.MKGeneralException,
            match="Syntax error in expression '3, T': too few operands"):
        utils.stack_resolver("3 T".split(), lambda x: x == "T",
                             lambda op, f, s: f + s, int)
def test_stack_resolver_exception():
    with pytest.raises(utils.MKGeneralException,
                       match="too many operands left"):
        utils.stack_resolver("1 2 3 +".split(), lambda x: x == "+",
                             lambda op, f, s: f + s, int)
def test_stack_resolver(elements, is_operator, apply_operator, apply_element,
                        result):
    assert utils.stack_resolver(elements, is_operator, apply_operator,
                                apply_element) == result