feat(model): Hoststack type
[csit.git] / resources / libraries / python / model / ExportResult.py
index b5de27e..dd09684 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2022 Cisco and/or its affiliates.
+# Copyright (c) 2023 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
@@ -18,7 +18,7 @@ from robot.libraries.BuiltIn import BuiltIn
 from resources.libraries.python.model.util import descend, get_export_data
 
 
 from resources.libraries.python.model.util import descend, get_export_data
 
 
-def export_dut_type_and_version(dut_type=u"unknown", dut_version=u"unknown"):
+def export_dut_type_and_version(dut_type="unknown", dut_version="unknown"):
     """Export the arguments as dut type and version.
 
     Robot tends to convert "none" into None, hence the unusual default values.
     """Export the arguments as dut type and version.
 
     Robot tends to convert "none" into None, hence the unusual default values.
@@ -32,32 +32,32 @@ def export_dut_type_and_version(dut_type=u"unknown", dut_version=u"unknown"):
     :type dut_version: Optiona[str]
     :raises RuntimeError: If value is neither in argument not robot variable.
     """
     :type dut_version: Optiona[str]
     :raises RuntimeError: If value is neither in argument not robot variable.
     """
-    if dut_type == u"unknown":
-        dut_type = BuiltIn().get_variable_value(u"\\${DUT_TYPE}", u"unknown")
-        if dut_type == u"unknown":
-            raise RuntimeError(u"Dut type not provided.")
+    if dut_type == "unknown":
+        dut_type = BuiltIn().get_variable_value("\\${DUT_TYPE}", "unknown")
+        if dut_type == "unknown":
+            raise RuntimeError("Dut type not provided.")
     else:
         # We want to set a variable in higher level suite setup
         # to be available to test setup several levels lower.
         BuiltIn().set_suite_variable(
     else:
         # We want to set a variable in higher level suite setup
         # to be available to test setup several levels lower.
         BuiltIn().set_suite_variable(
-            u"\\${DUT_TYPE}", dut_type, u"children=True"
+            "\\${DUT_TYPE}", dut_type, "children=True"
         )
         )
-    if dut_version == u"unknown":
+    if dut_version == "unknown":
         dut_version = BuiltIn().get_variable_value(
         dut_version = BuiltIn().get_variable_value(
-            u"\\${DUT_VERSION}", u"unknown"
+            "\\${DUT_VERSION}", "unknown"
         )
         )
-        if dut_type == u"unknown":
-            raise RuntimeError(u"Dut version not provided.")
+        if dut_type == "unknown":
+            raise RuntimeError("Dut version not provided.")
     else:
         BuiltIn().set_suite_variable(
     else:
         BuiltIn().set_suite_variable(
-            u"\\${DUT_VERSION}", dut_version, u"children=True"
+            "\\${DUT_VERSION}", dut_version, "children=True"
         )
     data = get_export_data()
         )
     data = get_export_data()
-    data[u"dut_type"] = dut_type.lower()
-    data[u"dut_version"] = dut_version
+    data["dut_type"] = dut_type.lower()
+    data["dut_version"] = dut_version
 
 
 
 
-def export_tg_type_and_version(tg_type=u"unknown", tg_version=u"unknown"):
+def export_tg_type_and_version(tg_type="unknown", tg_version="unknown"):
     """Export the arguments as tg type and version.
 
     Robot tends to convert "none" into None, hence the unusual default values.
     """Export the arguments as tg type and version.
 
     Robot tends to convert "none" into None, hence the unusual default values.
@@ -71,29 +71,29 @@ def export_tg_type_and_version(tg_type=u"unknown", tg_version=u"unknown"):
     :type tg_version: Optiona[str]
     :raises RuntimeError: If value is neither in argument not robot variable.
     """
     :type tg_version: Optiona[str]
     :raises RuntimeError: If value is neither in argument not robot variable.
     """
-    if tg_type == u"unknown":
-        tg_type = BuiltIn().get_variable_value(u"\\${TG_TYPE}", u"unknown")
-        if tg_type == u"unknown":
-            raise RuntimeError(u"TG type not provided.")
+    if tg_type == "unknown":
+        tg_type = BuiltIn().get_variable_value("\\${TG_TYPE}", "unknown")
+        if tg_type == "unknown":
+            raise RuntimeError("TG type not provided!")
     else:
         # We want to set a variable in higher level suite setup
         # to be available to test setup several levels lower.
         BuiltIn().set_suite_variable(
     else:
         # We want to set a variable in higher level suite setup
         # to be available to test setup several levels lower.
         BuiltIn().set_suite_variable(
-            u"\\${TG_TYPE}", tg_type, u"children=True"
+            "\\${TG_TYPE}", tg_type, "children=True"
         )
         )
-    if tg_version == u"unknown":
+    if tg_version == "unknown":
         tg_version = BuiltIn().get_variable_value(
         tg_version = BuiltIn().get_variable_value(
-            u"\\${TG_VERSION}", u"unknown"
+            "\\${TG_VERSION}", "unknown"
         )
         )
-        if tg_type == u"unknown":
-            raise RuntimeError(u"TG version not provided.")
+        if tg_type == "unknown":
+            raise RuntimeError("TG version not provided!")
     else:
         BuiltIn().set_suite_variable(
     else:
         BuiltIn().set_suite_variable(
-            u"\\${TG_VERSION}", tg_version, u"children=True"
+            "\\${TG_VERSION}", tg_version, "children=True"
         )
     data = get_export_data()
         )
     data = get_export_data()
-    data[u"tg_type"] = tg_type.lower()
-    data[u"tg_version"] = tg_version
+    data["tg_type"] = tg_type.lower()
+    data["tg_version"] = tg_version
 
 
 def append_mrr_value(mrr_value, unit):
 
 
 def append_mrr_value(mrr_value, unit):
@@ -109,10 +109,10 @@ def append_mrr_value(mrr_value, unit):
     if not unit:
         return
     data = get_export_data()
     if not unit:
         return
     data = get_export_data()
-    data[u"result"][u"type"] = u"mrr"
-    rate_node = descend(descend(data[u"result"], u"receive_rate"), "rate")
-    rate_node[u"unit"] = str(unit)
-    values_list = descend(rate_node, u"values", list)
+    data["result"]["type"] = "mrr"
+    rate_node = descend(descend(data["result"], "receive_rate"), "rate")
+    rate_node["unit"] = str(unit)
+    values_list = descend(rate_node, "values", list)
     values_list.append(float(mrr_value))
 
 
     values_list.append(float(mrr_value))
 
 
@@ -139,17 +139,17 @@ def export_search_bound(text, value, unit, bandwidth=None):
     """
     value = float(value)
     text = str(text).lower()
     """
     value = float(value)
     text = str(text).lower()
-    result_type = u"soak" if u"plrsearch" in text else u"ndrpdr"
-    upper_or_lower = u"upper" if u"upper" in text else u"lower"
-    ndr_or_pdr = u"ndr" if u"ndr" in text else u"pdr"
+    result_type = "soak" if "plrsearch" in text else "ndrpdr"
+    upper_or_lower = "upper" if "upper" in text else "lower"
+    ndr_or_pdr = "ndr" if "ndr" in text else "pdr"
 
 
-    result_node = get_export_data()[u"result"]
-    result_node[u"type"] = result_type
+    result_node = get_export_data()["result"]
+    result_node["type"] = result_type
     rate_item = dict(rate=dict(value=value, unit=unit))
     if bandwidth:
     rate_item = dict(rate=dict(value=value, unit=unit))
     if bandwidth:
-        rate_item[u"bandwidth"] = dict(value=float(bandwidth), unit=u"bps")
-    if result_type == u"soak":
-        descend(result_node, u"critical_rate")[upper_or_lower] = rate_item
+        rate_item["bandwidth"] = dict(value=float(bandwidth), unit="bps")
+    if result_type == "soak":
+        descend(result_node, "critical_rate")[upper_or_lower] = rate_item
         return
     descend(result_node, ndr_or_pdr)[upper_or_lower] = rate_item
 
         return
     descend(result_node, ndr_or_pdr)[upper_or_lower] = rate_item
 
@@ -169,14 +169,14 @@ def _add_latency(result_node, percent, whichward, latency_string):
     :type whichward: str
     :latency_string: str
     """
     :type whichward: str
     :latency_string: str
     """
-    l_min, l_avg, l_max, l_hdrh = latency_string.split(u"/", 3)
+    l_min, l_avg, l_max, l_hdrh = latency_string.split("/", 3)
     whichward_node = descend(result_node, f"latency_{whichward}")
     percent_node = descend(whichward_node, f"pdr_{percent}")
     whichward_node = descend(result_node, f"latency_{whichward}")
     percent_node = descend(whichward_node, f"pdr_{percent}")
-    percent_node[u"min"] = int(l_min)
-    percent_node[u"avg"] = int(l_avg)
-    percent_node[u"max"] = int(l_max)
-    percent_node[u"hdrh"] = l_hdrh
-    percent_node[u"unit"] = u"us"
+    percent_node["min"] = int(l_min)
+    percent_node["avg"] = int(l_avg)
+    percent_node["max"] = int(l_max)
+    percent_node["hdrh"] = l_hdrh
+    percent_node["unit"] = "us"
 
 
 def export_ndrpdr_latency(text, latency):
 
 
 def export_ndrpdr_latency(text, latency):
@@ -195,23 +195,25 @@ def export_ndrpdr_latency(text, latency):
     :type text: str
     :type latency: 1-tuple or 2-tuple of str
     """
     :type text: str
     :type latency: 1-tuple or 2-tuple of str
     """
-    result_node = get_export_data()[u"result"]
+    result_node = get_export_data()["result"]
     percent = 0
     percent = 0
-    if u"90" in text:
+    if "90" in text:
         percent = 90
         percent = 90
-    elif u"50" in text:
+    elif "50" in text:
         percent = 50
         percent = 50
-    elif u"10" in text:
+    elif "10" in text:
         percent = 10
         percent = 10
-    _add_latency(result_node, percent, u"forward", latency[0])
+    _add_latency(result_node, percent, "forward", latency[0])
     # Else TRex does not support latency measurement for this traffic profile.
     if len(latency) < 2:
         return
     # Else TRex does not support latency measurement for this traffic profile.
     if len(latency) < 2:
         return
-    _add_latency(result_node, percent, u"reverse", latency[1])
+    _add_latency(result_node, percent, "reverse", latency[1])
 
 
 def export_reconf_result(packet_rate, packet_loss, bandwidth):
 
 
 def export_reconf_result(packet_rate, packet_loss, bandwidth):
-    """Export the results from a reconf test.
+    """Export the RECONF type results.
+
+    Result type is set to reconf.
 
     :param packet_rate: Aggregate offered load in packets per second.
     :param packet_loss: How many of the packets were dropped or unsent.
 
     :param packet_rate: Aggregate offered load in packets per second.
     :param packet_loss: How many of the packets were dropped or unsent.
@@ -246,6 +248,56 @@ def export_reconf_result(packet_rate, packet_loss, bandwidth):
     )
 
 
     )
 
 
+def export_hoststack_results(
+        bandwidth, rate=None, rate_unit=None, latency=None,
+        failed_requests=None, completed_requests=None, retransmits=None,
+        duration=None
+):
+    """Export the HOSTSTACK type results.
+
+    Result type is set to hoststack.
+
+    :param bandwidth: Measured transfer rate using bps as a unit.
+    :param rate: Resulting rate measured by the test. [Optional]
+    :param rate_unit: CPS or RPS. [Optional]
+    :param latency: Measure latency. [Optional]
+    :param failed_requests: Number of failed requests. [Optional]
+    :param completed_requests: Number of completed requests. [Optional]
+    :param retransmits: Retransmitted TCP packets. [Optional]
+    :param duration: Measurment duration. [Optional]
+    :type bandwidth: float
+    :type rate: float
+    :type rate_unit: str
+    :type latency: float
+    :type failed_requests: int
+    :type completed_requests: int
+    :type retransmits: int
+    :type duration: float
+    """
+    result_node = get_export_data()["result"]
+    result_node["type"] = "hoststack"
+
+    result_node["bandwidth"] = dict(unit="bps", value=bandwidth)
+    if rate is not None:
+        result_node["rate"] = \
+            dict(unit=rate_unit, value=rate)
+    if latency is not None:
+        result_node["latency"] = \
+            dict(unit="ms", value=latency)
+    if failed_requests is not None:
+        result_node["failed_requests"] = \
+            dict(unit="requests", value=failed_requests)
+    if completed_requests is not None:
+        result_node["completed_requests"] = \
+            dict(unit="requests", value=completed_requests)
+    if retransmits is not None:
+        result_node["retransmits"] = \
+            dict(unit="packets", value=retransmits)
+    if duration is not None:
+        result_node["duration"] = \
+            dict(unit="s", value=duration)
+
+
 def append_telemetry(telemetry_item):
     """Append telemetry entry to proper place so it is dumped into json.
 
 def append_telemetry(telemetry_item):
     """Append telemetry entry to proper place so it is dumped into json.
 
@@ -253,4 +305,4 @@ def append_telemetry(telemetry_item):
     :type telemetry_item: str
     """
     data = get_export_data()
     :type telemetry_item: str
     """
     data = get_export_data()
-    data[u"telemetry"].append(telemetry_item)
+    data["telemetry"].append(telemetry_item)