From 5cca2e41b6f83968c2fcf256c564f27821e25b0b Mon Sep 17 00:00:00 2001
From: "Sridhar K. N. Rao" <sridhar.rao@spirent.com>
Date: Wed, 20 Feb 2019 20:53:27 +0530
Subject: pkt_gen: STC- Live Results Support

This patch adds live-results reporting from STC traffic generator.
STC reports per-port stream results every second. The results are
written to two different files in results folder.
Added configuration filename for stc-liveresults

JIRA: VSPERF-598

Change-Id: I37de6b5f544355e9e0dd42936328551b59afe065
Signed-off-by: Sridhar K. N. Rao <sridhar.rao@spirent.com>
---
 .../pkt_gen/testcenter/testcenter-rfc2544-rest.py  | 131 ++++++++++++++++++++-
 tools/pkt_gen/testcenter/testcenter.py             |   5 +
 2 files changed, 132 insertions(+), 4 deletions(-)

(limited to 'tools')

diff --git a/tools/pkt_gen/testcenter/testcenter-rfc2544-rest.py b/tools/pkt_gen/testcenter/testcenter-rfc2544-rest.py
index 4054d0e6..2f0cb0b4 100644
--- a/tools/pkt_gen/testcenter/testcenter-rfc2544-rest.py
+++ b/tools/pkt_gen/testcenter/testcenter-rfc2544-rest.py
@@ -26,6 +26,7 @@ import collections
 import logging
 import os
 import sqlite3
+import time
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -76,6 +77,46 @@ def write_query_results_to_csv(results_path, csv_results_file_prefix,
             result_file.write(row.replace(" ", ",") + "\n")
 
 
+def write_headers(results_path, file_name, rx_tx):
+    """ Write headers for the live-results files """
+    filec = os.path.join(results_path, file_name + rx_tx)
+    with open(filec, "a") as result_file:
+        if 'rx' in rx_tx:
+            result_file.write('Time,RxPrt,DrpFrCnt,SeqRnLen,AvgLat,' +
+                              'DrpFrRate,FrCnt,FrRate,MaxLat,MinLat,' +
+                              'OctCnt,OctRate\n')
+        else:
+            result_file.write('Time,StrId,BlkId,FrCnt,FrRate,ERxFrCnt,' +
+                              'OctCnt,OctRate,bitCnt,bitRate\n')
+
+
+def write_rx_live_results_to_file(results_path, file_name, results):
+    """ Write live results from the rx-ports"""
+    filec = os.path.join(results_path, file_name + ".rx")
+    with open(filec, "a") as result_file:
+        result_file.write('{0},{3},{1},{2},{4},{5},{6},{7},{8},{9},{10},{11}\n'
+                          .format(time.time(), results['DroppedFrameCount'],
+                                  results['SeqRunLength'], results['RxPort'],
+                                  results['AvgLatency'],
+                                  results['DroppedFrameRate'],
+                                  results['FrameCount'], results['FrameRate'],
+                                  results['MaxLatency'], results['MinLatency'],
+                                  results['OctetCount'], results['OctetRate']))
+
+
+def write_tx_live_results_to_file(results_path, file_name, results):
+    """ Write live results from the tx-ports"""
+    filec = os.path.join(results_path, file_name + ".tx")
+    with open(filec, "a") as result_file:
+        result_file.write('{0},{1},{9},{2},{3},{4},{5},{6},{7},{8}\n'
+                          .format(time.time(), results['StreamId'],
+                                  results['FrameCount'], results['FrameRate'],
+                                  results['ExpectedRxFrameCount'],
+                                  results['OctetCount'], results['OctetRate'],
+                                  results['BitCount'], results['BitRate'],
+                                  results['BlockId']))
+
+
 def positive_int(value):
     """ Positive Integer type for Arguments """
     ivalue = int(value)
@@ -311,6 +352,16 @@ def main():
                                 help=("IMIX specification as genome"
                                       "Encoding - RFC 6985"),
                                 dest="imix")
+    optional_named.add_argument("--live_results",
+                                required=False,
+                                action="store_true",
+                                help="Live Results required?",
+                                dest="live_results")
+    optional_named.add_argument("--logfile",
+                                required=False,
+                                default="./traffic_gen.log",
+                                help="Log file to log live results",
+                                dest="logfile")
     parser.add_argument("-v",
                         "--verbose",
                         required=False,
@@ -368,6 +419,10 @@ def main():
             _LOGGER.debug("Creating project ...")
         project = stc.get("System1", "children-Project")
 
+        # Configure the Result view
+        resultopts = stc.get('project1', 'children-resultoptions')
+        stc.config(resultopts, {'ResultViewMode': 'BASIC'})
+
         # Configure any custom traffic parameters
         if args.traffic_custom == "cont":
             if args.verbose:
@@ -554,14 +609,82 @@ def main():
             _LOGGER.debug("Apply configuration...")
         stc.apply()
 
+        # Register for the results
+        hResDataRx = stc.create('ResultDataSet', under='project1')
+        strmBlockList = stc.get('project1', 'children-streamblock')
+        stc.create('ResultQuery', under=hResDataRx, attributes={
+            'ResultRootList': strmBlockList,
+            'ConfigClassId': 'StreamBlock',
+            'ResultClassId': 'RxStreamSummaryResults',
+            'PropertyIdArray': "RxStreamSummaryResults.RxPort \
+                                RxStreamSummaryResults.AvgLatency \
+                                RxStreamSummaryResults.BitCount \
+                                RxStreamSummaryResults.BitRate \
+                                RxStreamSummaryResults.DroppedFrameCount\
+                                RxStreamSummaryResults.DroppedFrameRate \
+                                RxStreamSummaryResults.FrameCount \
+                                RxStreamSummaryResults.FrameRate \
+                                RxStreamSummaryResults.MaxLatency \
+                                RxStreamSummaryResults.MinLatency \
+                                RxStreamSummaryResults.OctetCount \
+                                RxStreamSummaryResults.OctetRate \
+                                RxStreamSummaryResults.SeqRunLength"})
+        hResDataTx = stc.create('ResultDataSet', under='project1')
+        strmBlockList = stc.get('project1', 'children-streamblock')
+        stc.create('ResultQuery', under=hResDataTx, attributes={
+            'ResultRootList': strmBlockList,
+            'ConfigClassId': 'StreamBlock',
+            'ResultClassId': 'TxStreamResults',
+            'PropertyIdArray': "TxStreamResults.BlockId \
+                                TxStreamResults.BitCount \
+                                TxStreamResults.BitRate \
+                                TxStreamResults.FrameCount \
+                                TxStreamResults.FrameRate \
+                                TxStreamResults.OctetCount \
+                                TxStreamResults.OctetRate"})
+        stc.perform('ResultDataSetSubscribe', params={'ResultDataSet': hResDataRx})
+        stc.perform('ResultDataSetSubscribe', params={'ResultDataSet': hResDataTx})
+        time.sleep(3)
+        stc.perform('RefreshResultView', params={'ResultDataSet': hResDataTx})
+        hndListRx = stc.get(hResDataRx, 'ResultHandleList')
+        hndListTx = stc.get(hResDataTx, 'ResultHandleList')
+
         if args.verbose:
             _LOGGER.debug("Starting the sequencer...")
         stc.perform("SequencerStart")
 
-        # Wait for sequencer to finish
-        _LOGGER.info(
-            "Starting test... Please wait for the test to complete...")
-        stc.wait_until_complete()
+        sequencer = stc.get("system1", "children-sequencer")
+        state = stc.get(sequencer, 'State')
+
+        # If Live-results are required, we don't wait for the test to complete
+        if args.live_results:
+            write_headers(args.vsperf_results_dir, args.logfile, '.rx')
+            write_headers(args.vsperf_results_dir, args.logfile, '.tx')
+            while state != 'IDLE':
+                state = stc.get(sequencer, 'State')
+                hndListTx = stc.get(hResDataTx, 'ResultHandleList')
+                if hndListTx:
+                    handles = hndListTx.split(' ')
+                    for handle in handles:
+                        tx_values = stc.get(handle)
+                        write_tx_live_results_to_file(args.vsperf_results_dir,
+                                                      args.logfile,
+                                                      tx_values)
+                if hndListRx:
+                    handles = hndListRx.split(' ')
+                    for handle in handles:
+                        rx_values = stc.get(handle)
+                        write_rx_live_results_to_file(args.vsperf_results_dir,
+                                                      args.logfile,
+                                                      rx_values)
+                time.sleep(1)
+        # Live results not needed, so just wait!
+        else:
+            # Wait for sequencer to finish
+            _LOGGER.info(
+                "Starting test... Please wait for the test to complete...")
+            stc.wait_until_complete()
+
         _LOGGER.info("The test has completed... Saving results...")
 
         # Determine what the results database filename is...
diff --git a/tools/pkt_gen/testcenter/testcenter.py b/tools/pkt_gen/testcenter/testcenter.py
index af30cd73..f01069e2 100644
--- a/tools/pkt_gen/testcenter/testcenter.py
+++ b/tools/pkt_gen/testcenter/testcenter.py
@@ -171,6 +171,7 @@ class TestCenter(trafficgen.ITrafficGenerator):
     Spirent TestCenter
     """
     _logger = logging.getLogger(__name__)
+    _liveresults_file = settings.getValue("TRAFFICGEN_STC_LIVERESULTS_FILE")
 
     def connect(self):
         """
@@ -437,6 +438,10 @@ class TestCenter(trafficgen.ITrafficGenerator):
                     genome = traffic['imix']['genome']
                     args.append('--imix' + ' ' + genome)
 
+        if settings.getValue("TRAFFICGEN_STC_LIVE_RESULTS") == "True":
+            args.append('--live_results')
+            args.append('--logfile' + ' ' + self._liveresults_file)
+
         if settings.getValue("TRAFFICGEN_STC_VERBOSE") == "True":
             args.append("--verbose")
             verbose = True
-- 
cgit