summaryrefslogtreecommitdiffstats
path: root/scripts/automation/regression/CShowParser.py
blob: 3445c70e4073eac638b6365a6174df9174878200 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#!/router/bin/python-2.7.4

import re
import misc_methods

class PlatformResponseMissmatch(Exception): 
    def __init__(self, message):
        # Call the base class constructor with the parameters it needs
        super(PlatformResponseMissmatch, self).__init__(message + ' is not available for given platform state and data.\nPlease make sure the relevant features are turned on in the platform.')

class PlatformResponseAmbiguity(Exception): 
    def __init__(self, message):
        # Call the base class constructor with the parameters it needs
        super(PlatformResponseAmbiguity, self).__init__(message + ' found more than one file matching the provided filename.\nPlease provide more distinct filename.')


class CShowParser(object):

    @staticmethod
    def parse_drop_stats (query_response, interfaces_list):
        res          = {'total_drops' : 0}
        response_lst = query_response.split('\r\n')
        mtch_found   = 0

        for line in response_lst:
            mtch = re.match("^\s*(\w+/\d/\d)\s+(\d+)\s+(\d+)", line)
            if mtch:
                mtch_found += 1
                if (mtch.group(1) in interfaces_list):
                    res[mtch.group(1)] = (int(mtch.group(2)) + int(mtch.group(3)))
                    res['total_drops'] += (int(mtch.group(2)) + int(mtch.group(3)))
#       if mtch_found == 0: # no matches found at all
#           raise PlatformResponseMissmatch('Drop stats')
#       else:
#           return res
        return res

    @staticmethod
    def parse_nbar_stats (query_response):
        response_lst = query_response.split('\r\n')
        stats        = {}
        final_stats  = {}
        mtch_found   = 0

        for line in response_lst:
            mtch = re.match("\s*([\w-]+)\s*(\d+)\s*(\d+)\s+", line)
            if mtch:
                mtch_found += 1
                key     = mtch.group(1)
                pkt_in  = int(mtch.group(2))
                pkt_out = int(mtch.group(3))

                avg_pkt_cnt = ( pkt_in + pkt_out )/2
                if avg_pkt_cnt == 0.0:
                    # escaping zero division case
                    continue
                if key in stats:
                    stats[key] += avg_pkt_cnt
                else:
                    stats[key] = avg_pkt_cnt
        
        # Normalize the results to percents
        for protocol in stats:
            protocol_norm_stat = int(stats[protocol]*10000/stats['Total'])/100.0 # round the result to x.xx format
            if (protocol_norm_stat != 0.0):
                final_stats[protocol] = protocol_norm_stat

        if mtch_found == 0: # no matches found at all
            raise PlatformResponseMissmatch('NBAR classification stats')
        else:
            return { 'percentage' : final_stats, 'packets' : stats }

    @staticmethod
    def parse_nat_stats (query_response):
        response_lst = query_response.split('\r\n')
        res          = {}
        mtch_found   = 0

        for line in response_lst:
            mtch = re.match("Total (active translations):\s+(\d+).*(\d+)\s+static,\s+(\d+)\s+dynamic", line)
            if mtch:
                mtch_found += 1
                res['total_active_trans']   = int(mtch.group(2))
                res['static_active_trans']  = int(mtch.group(3))
                res['dynamic_active_trans'] = int(mtch.group(4))
                continue

            mtch = re.match("(Hits):\s+(\d+)\s+(Misses):\s+(\d+)", line)
            if mtch:
                mtch_found += 1
                res['num_of_hits']   = int(mtch.group(2))
                res['num_of_misses'] = int(mtch.group(4))

        if mtch_found == 0: # no matches found at all
            raise PlatformResponseMissmatch('NAT translations stats')
        else:
            return res

    @staticmethod
    def parse_cpu_util_stats (query_response):
        response_lst = query_response.split('\r\n')
        res = { 'cpu0' : 0,
                'cpu1' : 0 }
        mtch_found = 0
        for line in response_lst:
            mtch = re.match("\W*Processing: Load\D*(\d+)\D*(\d+)\D*(\d+)\D*(\d+)\D*", line)
            if mtch:
                mtch_found += 1
                res['cpu0'] += float(mtch.group(1))
                res['cpu1'] += float(mtch.group(2))

        if mtch_found == 0: # no matches found at all
            raise PlatformResponseMissmatch('CPU utilization processing')
        else:
            res['cpu0'] = res['cpu0']/mtch_found
            res['cpu1'] = res['cpu1']/mtch_found
            return res

    @staticmethod
    def parse_cft_stats (query_response):
        response_lst = query_response.split('\r\n')
        res = {}
        mtch_found = 0
        for line in response_lst:
            mtch = re.match("\W*(\w+)\W*([:]|[=])\W*(\d+)", line)
            if mtch:
                mtch_found += 1
                res[ str( mix_string(m.group(1)) )] = float(m.group(3))
        if mtch_found == 0: # no matches found at all
            raise PlatformResponseMissmatch('CFT counters stats')
        else:
            return res


    @staticmethod
    def parse_cvla_memory_usage(query_response):
        response_lst = query_response.split('\r\n')
        res      = {}
        res2     = {}
        cnt      = 0
        state    = 0
        name     = ''
        number   = 0.0

        for line in response_lst:
            if state == 0:
                mtch = re.match("\W*Entity name:\W*(\w[^\r\n]+)", line)
                if mtch:
                    name = misc_methods.mix_string(mtch.group(1))
                    state = 1
                    cnt += 1
            elif state == 1:
                mtch = re.match("\W*Handle:\W*(\d+)", line)
                if mtch:
                    state = state + 1
                else:
                    state = 0;
            elif state == 2:
                mtch = re.match("\W*Number of allocations:\W*(\d+)", line)
                if mtch:
                    state = state + 1
                    number=float(mtch.group(1))
                else:
                    state = 0;
            elif state == 3:
                mtch = re.match("\W*Memory allocated:\W*(\d+)", line)
                if mtch:
                    state = 0
                    res[name]   = float(mtch.group(1))
                    res2[name]  = number
                else:
                    state = 0
        if cnt == 0:
            raise PlatformResponseMissmatch('CVLA memory usage stats')

        return (res,res2)

        
    @staticmethod
    def parse_show_image_version(query_response):
        response_lst = query_response.split('\r\n')
        res      = {}

        for line in response_lst:
            mtch = re.match("System image file is \"(\w+):(.*/)?(.+)\"", line)
            if mtch:
                res['drive'] = mtch.group(1)
                res['image'] = mtch.group(3)
                return res

        raise PlatformResponseMissmatch('Running image info')


    @staticmethod
    def parse_image_existence(query_response, img_name):
        response_lst = query_response.split('\r\n')
        cnt      = 0

        for line in response_lst:
            regex = re.compile(".* (?!include) %s" % img_name )
            mtch = regex.match(line)
            if mtch:
                cnt += 1
        if cnt == 1:
            return True
        elif cnt > 1:
            raise PlatformResponseAmbiguity('Image existence')
        else:
            return False

    @staticmethod
    def parse_file_copy (query_response):
        rev_response_lst = reversed(query_response.split('\r\n'))
        lines_parsed     = 0

        for line in rev_response_lst:
            mtch = re.match("\[OK - (\d+) bytes\]", line)
            if mtch:
                return True
            lines_parsed += 1

            if lines_parsed > 5:
                return False
        return False


if __name__ == "__main__":
    pass