Example #1
0
 def test_validate_gt(self):
     threshold = 100.0
     composite_metric = CompositeMetric(name="Test_Metric")
     metric = Metric(name="fail1", value=90.0)
     composite_metric.add(metric)
     metric = Metric(name="fail2", value=threshold)
     composite_metric.add(metric)
     metric = Metric(name="pass", value=110.0)
     composite_metric.add(metric)
     with pytest.raises(Rule.ThresholdViolation) as e:
         rule = Rule("/Test_Metric#fail1",
                     operation=Rule.Evaluation.GREATER_THAN,
                     limiting_value=threshold)
         rule.validate(composite_metric)
     assert f"/Test_Metric#fail1 <= {threshold}" in str(e)
     assert "#fail2" not in str(e)
     assert "#pass" not in str(e)
     with pytest.raises(Rule.ThresholdViolation) as e:
         rule = Rule("/Test_Metric#fail2",
                     operation=Rule.Evaluation.GREATER_THAN,
                     limiting_value=threshold)
         rule.validate(composite_metric)
     assert f"/Test_Metric#fail2 <= {threshold}" in str(e)
     assert "#fail1" not in str(e)
     assert "#pass" not in str(e)
     with pytest.raises(Rule.ThresholdViolation) as e:
         rule = Rule("/Test_Metric#*",
                     operation=Rule.Evaluation.GREATER_THAN,
                     limiting_value=threshold)
         rule.validate(composite_metric)
     assert f"/Test_Metric#fail1 <= {threshold}" in f"{e}"
     assert f"/Test_Metric#fail2 <= {threshold}" in f"{e}"
     assert "#pass" not in f"{e}"
Example #2
0
 def add_by_test(self, test_name: str, user_cpu_secs: float,
                 system_cpu_secs: float, duration: float):
     composite = CompositeMetric(name=test_name)
     composite.add(Metric(name="user_cpu", value=user_cpu_secs))
     composite.add(Metric(name="sys_cpu", value=system_cpu_secs))
     composite.add(Metric(name="duration", value=duration))
     self.by_test.add(composite)
Example #3
0
 def test_validate_lte(self):
     threshold = 100.0
     composite_metric = CompositeMetric(name="Test_Metric")
     metric = Metric(name="fail1", value=110.0)
     composite_metric.add(metric)
     metric = Metric(name="pass1", value=threshold)
     composite_metric.add(metric)
     metric = Metric(name="pass2", value=99.0)
     composite_metric.add(metric)
     with pytest.raises(Rule.ThresholdViolation) as e:
         rule = Rule("/Test_Metric#fail1",
                     operation=Rule.Evaluation.LESS_THAN_OR_EQUAL,
                     limiting_value=threshold)
         rule.validate(composite_metric)
     assert f"/Test_Metric#fail1 > {threshold}" in str(e)
     assert "#pass1" not in str(e)
     assert "#pass2" not in str(e)
     rule = Rule("/Test_Metric#fail2",
                 operation=Rule.Evaluation.LESS_THAN_OR_EQUAL,
                 limiting_value=threshold)
     # should not raise exception:
     rule.validate(composite_metric)
     with pytest.raises(Rule.ThresholdViolation) as e:
         rule = Rule("/Test_Metric#*",
                     operation=Rule.Evaluation.LESS_THAN_OR_EQUAL,
                     limiting_value=threshold)
         rule.validate(composite_metric)
     assert f"/Test_Metric#fail1 > {threshold}" in f"{e}"
     assert "#pass1" not in f"{e}"
     assert "#pass2" not in f"{e}"
Example #4
0
 def test_validate_exclusion(self):
     threshold = 100.0
     composite_metric = CompositeMetric(name="TestMetric")
     metric = Metric(name="fail1", value=99.0)
     composite_metric.add(metric)
     metric = Metric(name="pass1", value=threshold)
     composite_metric.add(metric)
     metric = Metric(name="pass2", value=110.0)
     composite_metric.add(metric)
     # Same test as above, but with exclusions:
     rule = Rule("/TestMetric#fail1",
                 operation=Rule.Evaluation.GREATER_THAN_OR_EQUAL,
                 limiting_value=threshold)
     rule.validate(composite_metric, exclusions={"/TestMetric*fail1"})
Example #5
0
    def validate(self,
                 composite_metric: CompositeMetric,
                 previous_metric: Optional[CompositeMetric] = None,
                 exclusions: Optional[Iterable[str]] = None) -> None:
        """
        Valide a composite metric for any and all matching key-names for each of its components

        :param composite_metric: the `CompositMetric` to validate
        :param previous_metric: previous value of the metric (for relative rule) or None if N/A or non-existent
        :raises: ValueError with a message containing the rules violated if the metric fails to validate
           against this rule
        """
        failed_elements: List[str] = []
        msg = ""

        for key in [
                k for k in composite_metric.keys(core_metrics_only=True)
                if not self._excluded(self._prepend_root(k, composite_metric),
                                      exclusions) and
            (self._pattern == '*' or fnmatch.fnmatchcase(
                self._prepend_root(k, composite_metric), self._pattern))
        ]:
            if self._is_relative:
                if not previous_metric:
                    continue
                try:
                    value = composite_metric[key].value - previous_metric[
                        key].value
                except KeyError:
                    continue  # prev metric does not contain this key, so nothing to compare to
            else:
                value = composite_metric[key].value
            if self._operation == Rule.Evaluation.LESS_THAN:
                if value >= self._limit:
                    msg += f"\n   {self._prepend_root(key, composite_metric)} >= {self._limit}"
                    failed_elements.append(key)
            elif self._operation == Rule.Evaluation.GREATER_THAN:
                if value <= self._limit:
                    msg += f"\n   {self._prepend_root(key, composite_metric)} <= {self._limit}"
                    failed_elements.append(key)
            elif self._operation == Rule.Evaluation.LESS_THAN_OR_EQUAL:
                if value > self._limit:
                    failed_elements.append(key)
                    msg += f"\n  {self._prepend_root(key, composite_metric)} > {self._limit}"
            elif self._operation == Rule.Evaluation.GREATER_THAN_OR_EQUAL:
                if value < self._limit:
                    failed_elements.append(key)
                    msg += f"\n  {self._prepend_root(key, composite_metric)} < {self._limit}"
        if failed_elements:
            raise Rule.ThresholdViolation(msg=msg,
                                          parent=composite_metric,
                                          offending_elements=failed_elements)
Example #6
0
    def test_to_dataclass_simple(self):
        metric = CompositeMetric("TestMetric")
        metric.add(Metric("one", 93.224556768))
        metric.add(Metric("two", 1.0))

        @dataclass
        class TestDataClass(MetricDataClass):
            one: float
            two: float

        data = metric.to_dataclass(TestDataClass)
        assert data.one == metric["one"].value
        assert data.two == metric["two"].value
Example #7
0
 def execute(self) -> QueryResult[MetricDataClassT]:
     # we order timestamps for query in descending order to filter out "the top" which are the newest items
     self._statement = self._statement.order_by(
         desc(SQLCompositeMetric.timestamp))
     if self._max_count:
         self._statement = self._statement.limit(self._max_count)
     sql_result: List[SQLCompositeMetric] = self._statement.all()
     result: QueryResult[MetricDataClassT] = QueryResult()
     for item in reversed(
             sql_result
     ):  # order timestamps from oldest to newest when returning to client
         flattened: Dict[str, float] = {}
         for child in item.children:
             flattened[child.name] = child.value
         metadata = Metadata({
             data.name: data.value
             for data in item.metrics_metadata.data
         })
         result.metadata.append(metadata)
         result.timestamps.append(item.timestamp)
         result.metric_data.append(
             CompositeMetric.from_flattened(flattened).to_dataclass(
                 self._type))
     return result
Example #8
0
    def test_to_dataclass_simple_with_dict(self):
        metric = CompositeMetric("TestMetric")
        metric.add(Metric("one", 93.224556768))
        metric.add(Metric("two", 1.0))
        inner = CompositeMetric("values")
        comp_inner1 = CompositeMetric("comp_one")
        comp_inner1.add(Metric("in_one", 23.354))
        comp_inner1.add(Metric("in_two", -23.354))
        inner.add(comp_inner1)
        comp_inner2 = CompositeMetric("comp_two")
        comp_inner2.add(Metric("in_one", 3455623.354))
        comp_inner2.add(Metric("in_two", -56576823.354))
        inner.add(comp_inner2)
        metric.add(inner)

        @dataclass
        class Inner(MetricDataClass):
            in_one: float
            in_two: float

        @dataclass
        class TestDataClass(MetricDataClass):
            one: float
            two: float
            values: Dict[str, Inner]

        data = metric.to_dataclass(TestDataClass)
        assert data.one == metric["one"].value
        assert data.two == metric["two"].value
        assert isinstance(data.values["comp_one"], Inner)
        assert data.values["comp_one"].in_one == inner.value["comp_one"].value[
            "in_one"].value
        assert data.values["comp_one"].in_two == inner.value["comp_one"].value[
            "in_two"].value
        assert data.values["comp_two"].in_one == inner.value["comp_two"].value[
            "in_one"].value
        assert data.values["comp_two"].in_two == inner.value["comp_two"].value[
            "in_two"].value
Example #9
0
    def test_to_dataclass_simple_with_dict_and_optionals(self):
        @dataclass
        class Inner(MetricDataClass):
            in_one: float
            in_two: Optional[float] = None

        @dataclass
        class TestDataClass(MetricDataClass):
            one: float
            two: Optional[float] = None
            values: Optional[Dict[str, Inner]] = None

        metric = CompositeMetric("TestMetric")
        metric.add(Metric("one", 93.224556768))

        data = metric.to_dataclass(TestDataClass)
        assert data.one == metric["one"].value
        assert data.two is None
        assert data.values is None

        metric.add(Metric("two", 1.0))
        data = metric.to_dataclass(TestDataClass)
        assert data.one == metric["one"].value
        assert data.two == metric["two"].value
        assert data.values is None

        inner = CompositeMetric("values")
        comp_inner1 = CompositeMetric("comp_one")
        comp_inner1.add(Metric("in_one", 23.354))
        comp_inner1.add(Metric("in_two", -23.354))
        inner.add(comp_inner1)
        metric.add(inner)
        metric.add(Metric("two", 1.0))
        data = metric.to_dataclass(TestDataClass)
        assert data.one == metric["one"].value
        assert data.two == metric["two"].value
        assert isinstance(data.values["comp_one"], Inner)
        assert data.values["comp_one"].in_one == inner.value["comp_one"].value[
            "in_one"].value
        assert data.values["comp_one"].in_two == inner.value["comp_one"].value[
            "in_two"].value

        comp_inner2 = CompositeMetric("comp_two")
        comp_inner2.add(Metric("in_one", 3455623.354))
        inner.add(comp_inner2)

        data = metric.to_dataclass(TestDataClass)
        assert data.one == metric["one"].value
        assert data.two == metric["two"].value
        assert isinstance(data.values["comp_one"], Inner)
        assert data.values["comp_one"].in_one == inner.value["comp_one"].value[
            "in_one"].value
        assert data.values["comp_one"].in_two == inner.value["comp_one"].value[
            "in_two"].value
        assert data.values["comp_two"].in_one == inner.value["comp_two"].value[
            "in_one"].value
        assert data.values["comp_two"].in_two == None
Example #10
0
 def test_invalid_name_raises_ValueError(self):
     with pytest.raises(ValueError):
         CompositeMetric("name_with_#")
     with pytest.raises(ValueError):
         CompositeMetric("name_with_/")
Example #11
0
 def test_keys(self):
     root = CompositeMetric("root_test_metric")
     child = CompositeMetric("child_test_metric")
     test_value2 = 3490.223
     test_value3 = -123.872
     root.add(child)
     root.add(Metric("pathed/test_metric2", test_value2))
     grandchild = CompositeMetric("grandchild_test_metric")
     child.add(grandchild)
     grandchild.add(Metric("test_metric3", test_value3))
     assert set(root.keys(core_metrics_only=True)) == {
         "child_test_metric/grandchild_test_metric#test_metric3",
         "#pathed/test_metric2"}
     assert set(root.keys()) == {
         "child_test_metric/grandchild_test_metric#test_metric3",
         "#pathed/test_metric2",
         "child_test_metric",
         "child_test_metric/grandchild_test_metric"}
     for key in root.keys(core_metrics_only=False):
         if '#' in key:
             assert isinstance(root[key], Metric)
         else:
             assert isinstance(root[key], CompositeMetric)
     assert root["child_test_metric"] == child
     with pytest.raises(KeyError):
         root["no_such_child"]
Example #12
0
 def test_from_dict(self):
     root = CompositeMetric("root_test_metric")
     child = CompositeMetric("child_test_metric")
     test_value2 = 3490.223
     test_value3 = -123.872
     root.add(child)
     root.add(Metric("pathed/test_metric2", test_value2))
     grandchild = CompositeMetric("grandchild_test_metric")
     child.add(grandchild)
     grandchild.add(Metric("test_metric3", test_value3))
     result = root.flatten()
     new_root = BasicMetric.from_flattened(result)
     assert result == new_root.flatten()
Example #13
0
 def test_flatten(self):
     root = CompositeMetric("root_test_metric")
     child = CompositeMetric("child_test_metric")
     test_value2 = 3490.223
     test_value3 = -123.872
     root.add(child)
     root.add(Metric("pathed/test_metric2", test_value2))
     grandchild = CompositeMetric("grandchild_test_metric")
     child.add(grandchild)
     grandchild.add(Metric("test_metric3", test_value3))
     result = root.flatten()
     assert len(root.value) == 2
     assert '/root_test_metric/child_test_metric/grandchild_test_metric#test_metric3' in result
     assert result['/root_test_metric/child_test_metric/grandchild_test_metric#test_metric3'] == test_value3
     assert '/root_test_metric#pathed/test_metric2' in result
     assert result['/root_test_metric#pathed/test_metric2'] == test_value2
Example #14
0
 def by_test(self):
     if self._by_test is None:
         self._by_test = CompositeMetric(name="by_test")
     return self._by_test
Example #15
0
 def by_pkg_composite(self):
     if self._by_pkg_metrics is None:
         self._by_pkg_metrics = CompositeMetric(name="by_file")
     return self._by_pkg_metrics
Example #16
0
def data_generator():
    seed = [1, 28832.12993, 0.00081238, 291]
    for index in range(100):
        top = CompositeMetric(name="TestMetric")
        child1 = Metric("child1", seed[0])
        child2 = CompositeMetric("child2")
        child3 = CompositeMetric("child3")
        top.add(child1)
        top.add(child2)
        top.add(child3)
        grandchild2_1 = Metric("grandchild1", seed[1])
        grandchild2_2 = Metric("grandchild2", seed[2])
        child2.add(grandchild2_1)
        child2.add(grandchild2_2)
        grandchild3_1 = Metric("grandchild1", seed[3])
        child3.add(grandchild3_1)
        yield top
        seed[0] += 1
        seed[1] *= 0.9992
        seed[2] *= 1.2
        seed[3] -= 2