openscap_report.scap_results_parser.data_structures.oval_node   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 81.43%

Importance

Changes 0
Metric Value
wmc 25
eloc 72
dl 0
loc 93
ccs 57
cts 70
cp 0.8143
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
B OvalNode.evaluate_tree() 0 15 6
B OvalNode._get_result_counts() 0 18 7
A OvalNode._eval_operator() 0 11 5
A OvalNode.as_dict() 0 2 1
A OvalNode.as_json() 0 2 1
A OvalNode.log_oval_tree() 0 13 5
1
# Copyright 2022, Red Hat, Inc.
2
# SPDX-License-Identifier: LGPL-2.1-or-later
3
4 1
import json
5 1
import logging
6 1
from collections import Counter
7 1
from typing import List
8
9 1
from openscap_report.dataclasses import asdict, dataclass, field
10
11 1
from .oval_result_eval import (EMPTY_RESULT, FULL_RESULT_TO_SHORT_RESULT,
12
                               SHORT_RESULT_TO_FULL_RESULT, OvalResult)
13 1
from .oval_test import OvalTest
14
15
16 1
@dataclass
17 1
class OvalNode:  # pylint: disable=R0902
18 1
    node_id: str
19 1
    node_type: str
20 1
    value: str
21 1
    negation: bool = False
22 1
    comment: str = ""
23 1
    tag: str = ""
24 1
    children: List['OvalNode'] = field(default_factory=list)
25 1
    test_info: OvalTest = None
26
27 1
    def as_dict(self):
28
        return asdict(self)
29
30 1
    def as_json(self):
31
        return json.dumps(self.as_dict())
32
33 1
    def log_oval_tree(self, level=0):
34
        out = ""
35
        negation_str = ""
36
        if self.negation:
37
            negation_str = "not "
38
        if self.node_type != "value":
39
            out = "  " * level + self.node_type + " = " + negation_str + self.value
40
        else:
41
            out = "  " * level + self.node_id + " = " + negation_str + self.value
42
        logging.info(out)
43
        if self.children is not None:
44
            for child in self.children:
45
                child.log_oval_tree(level + 1)
46
47 1
    def _get_result_counts(self):
48 1
        result = Counter(EMPTY_RESULT)
49 1
        for child in self.children:
50 1
            value = child.value
51 1
            if child.node_type != "value":
52 1
                value = str(child.evaluate_tree())
53
54 1
            node_result = FULL_RESULT_TO_SHORT_RESULT.get(value, value)
55
56 1
            key = f"number_of_{node_result}".replace(" ", "_")
57
58 1
            if child.value == "true" and child.negation:
59 1
                key = "number_of_false"
60 1
            elif child.value == "false" and child.negation:
61 1
                key = "number_of_true"
62
63 1
            result[key] += 1
64 1
        return result
65
66 1
    def _eval_operator(self, oval_result):
67 1
        out_result = None
68 1
        if self.node_type.lower() == "or":
69 1
            out_result = oval_result.eval_operator_or()
70 1
        elif self.node_type.lower() == "and":
71 1
            out_result = oval_result.eval_operator_and()
72 1
        elif self.node_type.lower() == "one":
73 1
            out_result = oval_result.eval_operator_one()
74 1
        elif self.node_type.lower() == "xor":
75 1
            out_result = oval_result.eval_operator_xor()
76 1
        return out_result
77
78 1
    def evaluate_tree(self):
79 1
        results_counts = self._get_result_counts()
80 1
        oval_result = OvalResult(**results_counts)
81 1
        out_result = None
82 1
        if oval_result.is_notapp_result():
83 1
            out_result = "notappl"
84
        else:
85 1
            out_result = self._eval_operator(oval_result)
86
87 1
        if out_result == "true" and self.negation:
88 1
            out_result = "false"
89 1
        elif out_result == "false" and self.negation:
90 1
            out_result = "true"
91
92
        return SHORT_RESULT_TO_FULL_RESULT.get(out_result, out_result)
93