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