update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[osm/SO.git] / rwlaunchpad / plugins / rwmonparam / test / utest_mon_params.py
1 #!/usr/bin/env python3
2
3 #
4 # Copyright 2016 RIFT.IO Inc
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18
19
20 import asyncio
21 import base64
22 import logging
23 import os
24 import sys
25 import tornado.escape
26 import tornado.platform.asyncio
27 import tornado.testing
28 import tornado.web
29 import unittest
30 import xmlrunner
31 import xmltodict, json
32
33 import rift.tasklets.rwmonparam.vnfr_core as mon_params
34
35
36 from gi.repository import VnfrYang
37
38 logger = logging.getLogger("mon_params_test.py")
39
40
41 class AsyncioTornadoTest(tornado.testing.AsyncHTTPTestCase):
42 def setUp(self):
43 self._loop = asyncio.get_event_loop()
44 super().setUp()
45
46 def get_new_ioloop(self):
47 return tornado.platform.asyncio.AsyncIOMainLoop()
48
49
50 class MonParamsPingStatsTest(AsyncioTornadoTest):
51 ping_path = r"/api/v1/ping/stats"
52 ping_response = {
53 'ping-request-tx-count': 5,
54 'ping-response-rx-count': 10
55 }
56
57 mon_param_msg = VnfrYang.YangData_RwProject_Project_VnfrCatalog_Vnfr_MonitoringParam()
58 mon_param_msg.from_dict({
59 'id': '1',
60 'name': 'ping-request-tx-count',
61 'json_query_method': "NAMEKEY",
62 'http_endpoint_ref': ping_path,
63 'value_type': "INT",
64 'description': 'no of ping requests',
65 'group_tag': 'Group1',
66 'widget_type': 'COUNTER',
67 'units': 'packets'
68 })
69
70 endpoint_msg = VnfrYang.YangData_RwProject_Project_VnfrCatalog_Vnfr_HttpEndpoint()
71 endpoint_msg.from_dict({
72 'path': ping_path,
73 'polling_interval_secs': 1,
74 'username': 'admin',
75 'password': 'password',
76 'headers': [{'key': 'TEST_KEY', 'value': 'TEST_VALUE'}],
77 })
78
79 def create_endpoint(self, endpoint_msg):
80 self.mon_port = self.get_http_port()
81 endpoint = mon_params.HTTPEndpoint(
82 logger,
83 self._loop,
84 "127.0.0.1",
85 self.endpoint_msg,
86 )
87 # For each creation, update the descriptor as well
88 endpoint_msg.port = self.mon_port
89
90 return endpoint
91
92 def create_mon_param(self):
93 return mon_params.MonitoringParam(logger, self.mon_param_msg)
94
95 def get_app(self):
96 class PingStatsHandler(tornado.web.RequestHandler):
97 def get(this):
98 test_header = this.request.headers.get('TEST_KEY')
99 if test_header is None or test_header != 'TEST_VALUE':
100 this.set_status(401)
101 this.finish()
102 return None
103
104 auth_header = this.request.headers.get('Authorization')
105 if auth_header is None or not auth_header.startswith('Basic '):
106 this.set_status(401)
107 this.set_header('WWW-Authenticate', 'Basic realm=Restricted')
108 this._transforms = []
109 this.finish()
110 return None
111
112 auth_header = auth_header.encode('ascii')
113 auth_decoded = base64.decodestring(auth_header[6:]).decode('ascii')
114 login, password = auth_decoded.split(':', 2)
115 login = login.encode('ascii')
116 password = password.encode('ascii')
117 is_auth = (login == b"admin" and password == b"password")
118
119 if not is_auth:
120 this.set_status(401)
121 this.set_header('WWW-Authenticate', 'Basic realm=Restricted')
122 this._transforms = []
123 this.finish()
124 return None
125
126 this.write(self.ping_response)
127
128 return tornado.web.Application([
129 (self.ping_path, PingStatsHandler),
130 ])
131
132 def test_value_convert(self):
133 float_con = mon_params.ValueConverter("DECIMAL")
134 int_con = mon_params.ValueConverter("INT")
135 text_con = mon_params.ValueConverter("STRING")
136
137 a = float_con.convert("1.23")
138 self.assertEqual(a, 1.23)
139
140 a = float_con.convert(1)
141 self.assertEqual(a, float(1))
142
143 t = text_con.convert(1.23)
144 self.assertEqual(t, "1.23")
145
146 t = text_con.convert("asdf")
147 self.assertEqual(t, "asdf")
148
149 i = int_con.convert(1.23)
150 self.assertEqual(i, 1)
151
152 def test_json_key_value_querier(self):
153 kv_querier = mon_params.JsonKeyValueQuerier(logger, "ping-request-tx-count")
154 value = kv_querier.query(tornado.escape.json_encode(self.ping_response))
155 self.assertEqual(value, 5)
156
157 def test_json_path_value_querier(self):
158 kv_querier = mon_params.JsonPathValueQuerier(logger, '$.ping-request-tx-count')
159 value = kv_querier.query(tornado.escape.json_encode(self.ping_response))
160 self.assertEqual(value, 5)
161
162 def test_object_path_value_querier(self):
163 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$.*['ping-request-tx-count']")
164 value = kv_querier.query(tornado.escape.json_encode(self.ping_response))
165 self.assertEqual(value, 5)
166
167 def test_endpoint(self):
168 @asyncio.coroutine
169 def run_test():
170 endpoint = self.create_endpoint(self.endpoint_msg)
171 resp = yield from endpoint.poll()
172 resp_json = tornado.escape.json_decode(resp)
173 self.assertEqual(resp_json["ping-request-tx-count"], 5)
174 self.assertEqual(resp_json["ping-response-rx-count"], 10)
175
176 self._loop.run_until_complete(
177 asyncio.wait_for(run_test(), 10, loop=self._loop)
178 )
179
180 def test_mon_param(self):
181 a = self.create_mon_param()
182 a.extract_value_from_response(tornado.escape.json_encode(self.ping_response))
183 self.assertEqual(a.current_value, 5)
184 self.assertEqual(a.msg.value_integer, 5)
185
186 def test_endpoint_poller(self):
187 endpoint = self.create_endpoint(self.endpoint_msg)
188 mon_param = self.create_mon_param()
189 poller = mon_params.EndpointMonParamsPoller(
190 logger, self._loop, endpoint, [mon_param],
191 )
192 poller.start()
193
194 self._loop.run_until_complete(asyncio.sleep(1, loop=self._loop))
195 self.assertEqual(mon_param.current_value, 5)
196
197 poller.stop()
198
199 def test_params_controller(self):
200 new_port = self.get_http_port()
201 # Update port after new port is initialized
202 self.endpoint_msg.port = new_port
203 ctrl = mon_params.VnfMonitoringParamsController(
204 logger, self._loop, "1", "127.0.0.1",
205 [self.endpoint_msg], [self.mon_param_msg],
206 )
207 ctrl.start()
208
209 self._loop.run_until_complete(asyncio.sleep(1, loop=self._loop))
210
211 ctrl.stop()
212
213 self.assertEqual(1, len(ctrl.mon_params))
214 mon_param = ctrl.mon_params[0]
215 self.assertEqual(mon_param.current_value, 5)
216
217
218 class AsyncioTornadoHttpsTest(tornado.testing.AsyncHTTPSTestCase):
219 def setUp(self):
220 self._loop = asyncio.get_event_loop()
221 super().setUp()
222
223 def get_new_ioloop(self):
224 return tornado.platform.asyncio.AsyncIOMainLoop()
225
226
227 class MonParamsPingStatsHttpsTest(AsyncioTornadoHttpsTest):
228 ping_path = r"/api/v1/ping/stats"
229 ping_response = {
230 'ping-request-tx-count': 5,
231 'ping-response-rx-count': 10
232 }
233
234 mon_param_msg = VnfrYang.YangData_RwProject_Project_VnfrCatalog_Vnfr_MonitoringParam()
235 mon_param_msg.from_dict({
236 'id': '1',
237 'name': 'ping-request-tx-count',
238 'json_query_method': "NAMEKEY",
239 'http_endpoint_ref': ping_path,
240 'value_type': "INT",
241 'description': 'no of ping requests',
242 'group_tag': 'Group1',
243 'widget_type': 'COUNTER',
244 'units': 'packets'
245 })
246
247 endpoint_msg = VnfrYang.YangData_RwProject_Project_VnfrCatalog_Vnfr_HttpEndpoint()
248 endpoint_msg.from_dict({
249 'path': ping_path,
250 'https': 'true',
251 'polling_interval_secs': 1,
252 'username': 'admin',
253 'password': 'password',
254 'headers': [{'key': 'TEST_KEY', 'value': 'TEST_VALUE'}],
255 })
256
257 def create_endpoint(self, endpoint_msg):
258 self.mon_port = self.get_http_port()
259 endpoint = mon_params.HTTPEndpoint(
260 logger,
261 self._loop,
262 "127.0.0.1",
263 self.endpoint_msg,
264 )
265 # For each creation, update the descriptor as well
266 endpoint_msg.port = self.mon_port
267
268 return endpoint
269
270 def create_mon_param(self):
271 return mon_params.MonitoringParam(logger, self.mon_param_msg)
272
273 def get_app(self):
274 class PingStatsHandler(tornado.web.RequestHandler):
275 def get(this):
276 test_header = this.request.headers.get('TEST_KEY')
277 if test_header is None or test_header != 'TEST_VALUE':
278 this.set_status(401)
279 this.finish()
280 return None
281
282 auth_header = this.request.headers.get('Authorization')
283 if auth_header is None or not auth_header.startswith('Basic '):
284 this.set_status(401)
285 this.set_header('WWW-Authenticate', 'Basic realm=Restricted')
286 this._transforms = []
287 this.finish()
288 return None
289
290 auth_header = auth_header.encode('ascii')
291 auth_decoded = base64.decodestring(auth_header[6:]).decode('ascii')
292 login, password = auth_decoded.split(':', 2)
293 login = login.encode('ascii')
294 password = password.encode('ascii')
295 is_auth = (login == b"admin" and password == b"password")
296
297 if not is_auth:
298 this.set_status(401)
299 this.set_header('WWW-Authenticate', 'Basic realm=Restricted')
300 this._transforms = []
301 this.finish()
302 return None
303
304 this.write(self.ping_response)
305
306 return tornado.web.Application([
307 (self.ping_path, PingStatsHandler),
308 ])
309
310 def test_value_convert(self):
311 float_con = mon_params.ValueConverter("DECIMAL")
312 int_con = mon_params.ValueConverter("INT")
313 text_con = mon_params.ValueConverter("STRING")
314
315 a = float_con.convert("1.23")
316 self.assertEqual(a, 1.23)
317
318 a = float_con.convert(1)
319 self.assertEqual(a, float(1))
320
321 t = text_con.convert(1.23)
322 self.assertEqual(t, "1.23")
323
324 t = text_con.convert("asdf")
325 self.assertEqual(t, "asdf")
326
327 i = int_con.convert(1.23)
328 self.assertEqual(i, 1)
329
330 def test_json_key_value_querier(self):
331 kv_querier = mon_params.JsonKeyValueQuerier(logger, "ping-request-tx-count")
332 value = kv_querier.query(tornado.escape.json_encode(self.ping_response))
333 self.assertEqual(value, 5)
334
335 def test_endpoint(self):
336 @asyncio.coroutine
337 def run_test():
338 endpoint = self.create_endpoint(self.endpoint_msg)
339 resp = yield from endpoint.poll()
340 resp_json = tornado.escape.json_decode(resp)
341 self.assertEqual(resp_json["ping-request-tx-count"], 5)
342 self.assertEqual(resp_json["ping-response-rx-count"], 10)
343
344 self._loop.run_until_complete(
345 asyncio.wait_for(run_test(), 10, loop=self._loop)
346 )
347
348 def test_mon_param(self):
349 a = self.create_mon_param()
350 a.extract_value_from_response(tornado.escape.json_encode(self.ping_response))
351 self.assertEqual(a.current_value, 5)
352 self.assertEqual(a.msg.value_integer, 5)
353
354 def test_endpoint_poller(self):
355 endpoint = self.create_endpoint(self.endpoint_msg)
356 mon_param = self.create_mon_param()
357 poller = mon_params.EndpointMonParamsPoller(
358 logger, self._loop, endpoint, [mon_param],
359 )
360 poller.start()
361
362 self._loop.run_until_complete(asyncio.sleep(1, loop=self._loop))
363 self.assertEqual(mon_param.current_value, 5)
364
365 poller.stop()
366
367 def test_params_controller(self):
368 new_port = self.get_http_port()
369 # Update port after new port is initialized
370 self.endpoint_msg.port = new_port
371 ctrl = mon_params.VnfMonitoringParamsController(
372 logger, self._loop, "1", "127.0.0.1",
373 [self.endpoint_msg], [self.mon_param_msg],
374 )
375 ctrl.start()
376
377 self._loop.run_until_complete(asyncio.sleep(1, loop=self._loop))
378
379 ctrl.stop()
380
381 self.assertEqual(1, len(ctrl.mon_params))
382 mon_param = ctrl.mon_params[0]
383 self.assertEqual(mon_param.current_value, 5)
384
385
386 class VRouterStatsTest(unittest.TestCase):
387 system_response = {
388 "system": {
389 "cpu": [
390 {
391 "usage": 2.35,
392 "cpu": "all"
393 },
394 {
395 "usage": 5.35,
396 "cpu": "1"
397 }
398 ]
399 }
400 }
401
402 def test_object_path_value_querier(self):
403 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$.system.cpu[@.cpu is 'all'].usage")
404 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
405 self.assertEqual(value, 2.35)
406
407
408 class TrafsinkStatsTest(unittest.TestCase):
409 system_response = {
410 "rw-vnf-base-opdata:port-state": [
411 {
412 "ip": [
413 {
414 "address": "12.0.0.3/24"
415 }
416 ],
417 "rw-trafgen-data:trafgen-info": {
418 "src_l4_port": 1234,
419 "dst_l4_port": 5678,
420 "dst_ip_address": "192.168.1.1",
421 "tx_state": "Off",
422 "dst_mac_address": "00:00:00:00:00:00",
423 "tx_mode": "single-template",
424 "packet-count": 0,
425 "tx-cycles": 5478,
426 "tx_burst": 16,
427 "src_ip_address": "192.168.0.1",
428 "pkt_size": 64,
429 "src_mac_address": "fa:16:3e:07:b1:52",
430 "descr-string": "",
431 "tx_rate": 100
432 },
433 "counters": {
434 "input-errors": 0,
435 "output-bytes": 748,
436 "input-pause-xoff-pkts": 0,
437 "input-badcrc-pkts": 0,
438 "input-bytes": 62,
439 "rx-rate-mbps": 9576,
440 "output-pause-xoff-pkts": 0,
441 "input-missed-pkts": 0,
442 "input-packets": 1,
443 "output-errors": 0,
444 "tx-rate-mbps": 0,
445 "input-pause-xon-pkts": 0,
446 "output-pause-xon-pkts": 0,
447 "tx-rate-pps": 0,
448 "input-mcast-pkts": 0,
449 "rx-rate-pps": 0,
450 "output-packets": 6,
451 "input-nombuf-pkts": 0
452 },
453 "info": {
454 "numa-socket": 0,
455 "transmit-queues": 1,
456 "privatename": "eth_uio:pci=0000:00:04.0",
457 "duplex": "full-duplex",
458 "virtual-fabric": "No",
459 "link-state": "up",
460 "rte-port-id": 0,
461 "fastpath-instance": 1,
462 "id": 0,
463 "app-name": "rw_trafgen",
464 "speed": 10000,
465 "receive-queues": 1,
466 "descr-string": "",
467 "mac": "fa:16:3e:07:b1:52"
468 },
469 "portname": "trafsink_vnfd/cp0",
470 "queues": {
471 "rx-queue": [
472 {
473 "packets": 1,
474 "bytes-MB": 0,
475 "qid": 0,
476 "rate-mbps": 0,
477 "rate-pps": 0
478 }
479 ],
480 "tx-queue": [
481 {
482 "bytes-MB": 0,
483 "packets": 6,
484 "rate-pps": 0,
485 "errors": 0,
486 "qid": 0,
487 "rate-mbps": 0
488 }
489 ]
490 }
491 }
492 ]
493 }
494
495 def test_object_path_value_querier(self):
496 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$..*[@.portname is 'trafsink_vnfd/cp0'].counters.'rx-rate-mbps'")
497 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
498 self.assertEqual(value, 9576)
499
500 class IkeStatsTest(unittest.TestCase):
501 system_response = {
502 "rw-ipsec:ipsec-service-statistics": [
503 {
504 "name": "client1",
505 "statistics": {
506 "esp": {
507 "rx-bytes": 0,
508 "rx-packets": 0,
509 "tx-bytes": 0,
510 "tx-packets": 0
511 },
512 "rekey": {
513 "total": 3321,
514 "rate": 132,
515 "instantaneous-rate": 2
516 },
517 "state": {
518 "ike-sas": 10,
519 "threads-in-use": 5,
520 "swanctl-dir": "\/tmp\/strongswan4x3dni"
521 }
522 }
523 },
524 {
525 "name": "client0",
526 "statistics": {
527 "esp": {
528 "rx-bytes": 0,
529 "rx-packets": 0,
530 "tx-bytes": 0,
531 "tx-packets": 0
532 },
533 "rekey": {
534 "total": 3345,
535 "rate": 0,
536 "instantaneous-rate": 0
537 },
538 "state": {
539 "ike-sas": 50,
540 "threads-in-use": 5,
541 "swanctl-dir": "\/tmp\/strongswann21td3"
542 }
543 }
544 }
545 ]
546 }
547
548
549 def test_object_path_value_querier(self):
550 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$..*[@.name is 'client1'].statistics.rekey.rate")
551 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
552 self.assertEqual(value, 132)
553 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$..*[@.name is 'client1'].statistics.state.'ike-sas'")
554 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
555 self.assertEqual(value, 10)
556
557
558
559
560 class PortLatencyTest(unittest.TestCase):
561 system_response = {
562 "rw-vnf-base-opdata:port-state": [
563 {
564 "info": {
565 "fastpath-instance": 1,
566 "duplex": "full-duplex",
567 "link-state": "up",
568 "lport-id": 81931,
569 "mtu": 1500,
570 "descr-string": "",
571 "transmit-queues": 1,
572 "mac": "fa:16:3e:c7:4a:b8",
573 "admin-state": "up",
574 "rte-port-id": 0,
575 "numa-socket": 0,
576 "app-name": "rw_trafgen",
577 "speed": 10000,
578 "virtual-fabric": "No",
579 "id": 0,
580 "receive-queues": 1,
581 "privatename": "eth_uio:pci=0000:00:04.0"
582 },
583 "rw-trafgen-data:trafgen-info": {
584 "maximum-latency": 124412,
585 "latency-distribution": [
586 {
587 "range-end": 100,
588 "range-start": 0,
589 "packets": 0
590 },
591 {
592 "range-end": 200,
593 "range-start": 101,
594 "packets": 0
595 },
596 {
597 "range-end": 300,
598 "range-start": 201,
599 "packets": 0
600 },
601 {
602 "range-end": 400,
603 "range-start": 301,
604 "packets": 0
605 },
606 {
607 "range-end": 500,
608 "range-start": 401,
609 "packets": 0
610 },
611 {
612 "range-end": 600,
613 "range-start": 501,
614 "packets": 0
615 },
616 {
617 "range-end": 700,
618 "range-start": 601,
619 "packets": 0
620 },
621 {
622 "range-end": 800,
623 "range-start": 701,
624 "packets": 0
625 },
626 {
627 "range-end": 900,
628 "range-start": 801,
629 "packets": 0
630 },
631 {
632 "range-end": 1000,
633 "range-start": 901,
634 "packets": 0
635 },
636 {
637 "range-end": 1100,
638 "range-start": 1001,
639 "packets": 0
640 },
641 {
642 "range-end": 1200,
643 "range-start": 1101,
644 "packets": 0
645 },
646 {
647 "range-end": 1300,
648 "range-start": 1201,
649 "packets": 0
650 },
651 {
652 "range-end": 1400,
653 "range-start": 1301,
654 "packets": 0
655 },
656 {
657 "range-end": 1500,
658 "range-start": 1401,
659 "packets": 0
660 },
661 {
662 "range-end": 0,
663 "range-start": 1501,
664 "packets": 1513641
665 }
666 ],
667 "descr-string": "",
668 "tx_mode": "range-template",
669 "minimum-latency": 1928,
670 "pkt_size": 512,
671 "tx_rate": 100,
672 "tx-cycles": 35206,
673 "src_ip_address": "12.0.0.3",
674 "src_l4_port": 10000,
675 "dst_ip_address": "12.0.0.2",
676 "mean-deviation": 4500,
677 "queue": [
678 {
679 "maximum": 124412,
680 "num-packets": 1513641,
681 "average": 12112,
682 "mean-deviation": 4500,
683 "qid": 0,
684 "minimum": 1928
685 }
686 ],
687 "packet-count": 0,
688 "average-latency": 12112,
689 "dst_l4_port": 5678,
690 "tx_state": "On",
691 "tx_burst": 16
692 },
693 "counters": {
694 "tx-rate-pps": 139630,
695 "rx-rate-mbps": 232,
696 "tx-rate-mbps": 589,
697 "output-packets": 49285239,
698 "input-missed-pkts": 0,
699 "output-errors": 0,
700 "input-nombuf-pkts": 0,
701 "input-errors": 0,
702 "input-mcast-pkts": 0,
703 "output-bytes": 26022584932,
704 "input-packets": 22537250,
705 "input-bytes": 11899650400,
706 "rx-rate-pps": 55158
707 },
708 "portname": "trafgencp0",
709 "ip": [
710 {
711 "address": "12.0.0.3\/24"
712 }
713 ],
714 "queues": {
715 "rx-queue": [
716 {
717 "packets": 22537250,
718 "bytes-MB": 95197,
719 "rate-mbps": 232,
720 "qid": 0,
721 "rate-pps": 55158
722 }
723 ],
724 "tx-queue": [
725 {
726 "bytes-MB": 208180,
727 "packets": 49285239,
728 "errors": 0,
729 "rate-mbps": 589,
730 "qid": 0,
731 "rate-pps": 139630
732 }
733 ]
734 },
735 "extended-stats": {
736 "xstats": [
737 {
738 "name": "rx_good_packets",
739 "value": 22555470
740 },
741 {
742 "name": "tx_good_packets",
743 "value": 49337664
744 },
745 {
746 "name": "rx_good_bytes",
747 "value": 11458161160
748 },
749 {
750 "name": "tx_good_bytes",
751 "value": 25063512052
752 },
753 {
754 "name": "rx_errors",
755 "value": 0
756 },
757 {
758 "name": "tx_errors",
759 "value": 0
760 },
761 {
762 "name": "rx_mbuf_allocation_errors",
763 "value": 0
764 },
765 {
766 "name": "rx_q0_packets",
767 "value": 22555470
768 },
769 {
770 "name": "rx_q0_bytes",
771 "value": 11458161160
772 },
773 {
774 "name": "rx_q0_errors",
775 "value": 0
776 },
777 {
778 "name": "tx_q0_packets",
779 "value": 49337664
780 },
781 {
782 "name": "tx_q0_bytes",
783 "value": 25063512052
784 },
785 {
786 "name": "rx_q0_good_packets",
787 "value": 22555470
788 },
789 {
790 "name": "rx_q0_good_bytes",
791 "value": 11458161160
792 },
793 {
794 "name": "rx_q0_multicast_packets",
795 "value": 0
796 },
797 {
798 "name": "rx_q0_broadcast_packets",
799 "value": 0
800 },
801 {
802 "name": "rx_q0_undersize_packets",
803 "value": 38
804 },
805 {
806 "name": "rx_q0_size_64_packets",
807 "value": 0
808 },
809 {
810 "name": "rx_q0_size_65_127_packets",
811 "value": 0
812 },
813 {
814 "name": "rx_q0_size_128_255_packets",
815 "value": 0
816 },
817 {
818 "name": "rx_q0_size_256_511_packets",
819 "value": 22555432
820 },
821 {
822 "name": "rx_q0_size_512_1023_packets",
823 "value": 0
824 },
825 {
826 "name": "rx_q0_size_1024_1517_packets",
827 "value": 0
828 },
829 {
830 "name": "rx_q0_size_1518_max_packets",
831 "value": 0
832 },
833 {
834 "name": "tx_q0_good_packets",
835 "value": 49337664
836 },
837 {
838 "name": "tx_q0_good_bytes",
839 "value": 25063512052
840 },
841 {
842 "name": "tx_q0_errors",
843 "value": 0
844 },
845 {
846 "name": "tx_q0_multicast_packets",
847 "value": 18
848 },
849 {
850 "name": "tx_q0_broadcast_packets",
851 "value": 11
852 },
853 {
854 "name": "tx_q0_undersize_packets",
855 "value": 40
856 },
857 {
858 "name": "tx_q0_size_64_packets",
859 "value": 0
860 },
861 {
862 "name": "tx_q0_size_65_127_packets",
863 "value": 5
864 },
865 {
866 "name": "tx_q0_size_128_255_packets",
867 "value": 2
868 },
869 {
870 "name": "tx_q0_size_256_511_packets",
871 "value": 49337617
872 },
873 {
874 "name": "tx_q0_size_512_1023_packets",
875 "value": 0
876 },
877 {
878 "name": "tx_q0_size_1024_1517_packets",
879 "value": 0
880 },
881 {
882 "name": "tx_q0_size_1518_max_packets",
883 "value": 0
884 }
885 ]
886 },
887 "lacp-info": {
888 "state": {
889 "distributing": "On",
890 "active": "Off",
891 "collecting": "On"
892 },
893 "counters": {
894 "marker": {
895 "rx": 0,
896 "tx": 0,
897 "errors": 0,
898 "nobuf": 0
899 },
900 "lacppdu": {
901 "rx": 0,
902 "tx": 0,
903 "errors": 0,
904 "nobuf": 0
905 }
906 }
907 }
908 }
909 ]
910 }
911
912
913 def test_object_path_value_querier(self):
914 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$..*[@.portname is 'trafgencp0'].'rw-trafgen-data:trafgen-info'.pkt_size")
915 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
916 self.assertEqual(value, 512)
917 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$..*[@.portname is 'trafgencp0'].'rw-trafgen-data:trafgen-info'.'average-latency'")
918 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
919 self.assertEqual(value, 12112)
920
921
922 class vCPEStatTest(unittest.TestCase):
923 system_response = {"timestamp":1473455051,
924 "applicationLoad":[
925 { "service":"RIF", "instance":1, "gtpMessagesPerSec":0},
926 {"service":"CPE", "instance":1, "tps":0},
927 {"service":"DPE", "instance":1, "uplinkThroughput4G":0, "downlinkThroughput4G":0, "numDefaultBearers":0, "numDedicatedBearers":0 },
928 {"service":"VEM", "instance":1 },
929 {"service":"CDF", "instance":1, "tps":0},
930 {"service":"S6A", "instance":1, "tps":0},
931 {"service":"SDB", "instance":1, "queriesPerSec":0 }],
932 "resourceLoad":[
933 { "service":"RIF", "instance":1, "cpu":0, "mem":18, "compCpu":0 },
934 { "service":"CPE", "instance":1, "cpu":0, "mem":26, "compCpu":0 },
935 { "service":"DPE", "instance":1, "cpu":0, "mem":31, "compCpu":0 },
936 { "service":"VEM", "instance":1, "cpu":1, "mem":34, "compCpu":0 },
937 { "service":"CDF", "instance":1, "cpu":0, "mem":18, "compCpu":0 },
938 { "service":"S6A", "instance":1, "cpu":1, "mem":21, "compCpu":0 },
939 { "service":"SDB", "instance":1, "memUsedByData":255543560, "swapUtil":0, "swapTotal":3689934848, "swapUsed":0,"memUtil":0, "memTotal":12490944512, "memFree":10986942464, "cpu":2}] }
940
941
942 def test_object_path_value_querier(self):
943 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$.applicationLoad[@.service is 'DPE'].uplinkThroughput4G")
944 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
945 self.assertEqual(value, 0)
946 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$.resourceLoad[@.service is 'DPE'].mem")
947 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
948 self.assertEqual(value, 31)
949
950
951 class XMLReponseTest(unittest.TestCase):
952 xml_response = "<response status='success'><result> <entry> <current>2</current> <vsys>1</vsys> <maximum>0</maximum> <throttled>0</throttled> </entry> </result></response>"
953 try:
954 op = xmltodict.parse(xml_response)
955 x=json.dumps(op)
956 y=json.loads(x)
957 system_response = y
958 except Exception as e:
959 print("Input is Not XML formatted")
960 pass
961
962 def test_object_path_value_querier(self):
963 kv_querier = mon_params.ObjectPathValueQuerier(logger, "$.response.result.entry.current")
964 value = kv_querier.query(tornado.escape.json_encode(self.system_response))
965 self.assertEqual(value, '2')
966
967 def main(argv=sys.argv[1:]):
968
969 # The unittest framework requires a program name, so use the name of this
970 # file instead (we do not want to have to pass a fake program name to main
971 # when this is called from the interpreter).
972 unittest.main(
973 argv=[__file__] + argv,
974 testRunner=xmlrunner.XMLTestRunner(output=os.environ["RIFT_MODULE_TEST"])
975 )
976
977 if __name__ == '__main__':
978 main()
979