+ if u"-gbps" in plot_title:
+ value = u"gbps"
+ h_unit = u"Gbps"
+ multiplier = 1e6
+ else:
+ value = u"throughput"
+ h_unit = u"Mpps"
+ multiplier = 1.0
+
+ for ttype in plot.get(u"test-type", (u"ndr", u"pdr")):
+ y_vals = OrderedDict()
+ for item in plot.get(u"include", tuple()):
+ reg_ex = re.compile(str(item).lower())
+ for job in data:
+ for build in job:
+ for test_id, test in build.iteritems():
+ if re.match(reg_ex, str(test_id).lower()):
+ if y_vals.get(test[u"parent"], None) is None:
+ y_vals[test[u"parent"]] = {
+ u"1": list(),
+ u"2": list(),
+ u"4": list()
+ }
+ try:
+ if test[u"type"] not in (u"NDRPDR", u"CPS"):
+ continue
+
+ if u"1C" in test[u"tags"]:
+ y_vals[test[u"parent"]][u"1"].append(
+ test[value][ttype.upper()][u"LOWER"] *
+ multiplier
+ )
+ elif u"2C" in test[u"tags"]:
+ y_vals[test[u"parent"]][u"2"].append(
+ test[value][ttype.upper()][u"LOWER"] *
+ multiplier
+ )
+ elif u"4C" in test[u"tags"]:
+ y_vals[test[u"parent"]][u"4"].append(
+ test[value][ttype.upper()][u"LOWER"] *
+ multiplier
+ )
+ except (KeyError, TypeError):
+ pass
+
+ if not y_vals:
+ logging.warning(f"No data for the plot {plot.get(u'title', u'')}")
+ return
+
+ y_1c_max = dict()
+ for test_name, test_vals in y_vals.items():
+ for key, test_val in test_vals.items():
+ if test_val:
+ avg_val = sum(test_val) / len(test_val)
+ y_vals[test_name][key] = [avg_val, len(test_val)]
+ ideal = avg_val / (int(key) * 1e6)
+ if test_name not in y_1c_max or ideal > y_1c_max[test_name]:
+ y_1c_max[test_name] = ideal
+
+ vals = OrderedDict()
+ y_max = list()
+ nic_limit = 0
+ lnk_limit = 0
+ pci_limit = 0
+ for test_name, test_vals in y_vals.items():
+ try:
+ if test_vals[u"1"][1]:
+ name = re.sub(
+ REGEX_NIC,
+ u"",
+ test_name.replace(u'-ndrpdr', u'').
+ replace(u'2n1l-', u'')
+ )
+ vals[name] = OrderedDict()
+ y_val_1 = test_vals[u"1"][0] / 1e6
+ y_val_2 = test_vals[u"2"][0] / 1e6 if test_vals[u"2"][0] \
+ else None
+ y_val_4 = test_vals[u"4"][0] / 1e6 if test_vals[u"4"][0] \
+ else None
+
+ vals[name][u"val"] = [y_val_1, y_val_2, y_val_4]
+ vals[name][u"rel"] = [1.0, None, None]
+ vals[name][u"ideal"] = [
+ y_1c_max[test_name],
+ y_1c_max[test_name] * 2,
+ y_1c_max[test_name] * 4
+ ]
+ vals[name][u"diff"] = [
+ (y_val_1 - y_1c_max[test_name]) * 100 / y_val_1,
+ None,
+ None
+ ]
+ vals[name][u"count"] = [
+ test_vals[u"1"][1],
+ test_vals[u"2"][1],
+ test_vals[u"4"][1]
+ ]
+
+ try:
+ val_max = max(vals[name][u"val"])
+ except ValueError as err:
+ logging.error(repr(err))
+ continue
+ if val_max:
+ y_max.append(val_max)
+
+ if y_val_2:
+ vals[name][u"rel"][1] = round(y_val_2 / y_val_1, 2)
+ vals[name][u"diff"][1] = \
+ (y_val_2 - vals[name][u"ideal"][1]) * 100 / y_val_2
+ if y_val_4:
+ vals[name][u"rel"][2] = round(y_val_4 / y_val_1, 2)
+ vals[name][u"diff"][2] = \
+ (y_val_4 - vals[name][u"ideal"][2]) * 100 / y_val_4
+ except IndexError as err:
+ logging.warning(f"No data for {test_name}")
+ logging.warning(repr(err))
+
+ # Limits:
+ if u"x520" in test_name:
+ limit = plot[u"limits"][u"nic"][u"x520"]
+ elif u"x710" in test_name:
+ limit = plot[u"limits"][u"nic"][u"x710"]
+ elif u"xxv710" in test_name:
+ limit = plot[u"limits"][u"nic"][u"xxv710"]
+ elif u"xl710" in test_name:
+ limit = plot[u"limits"][u"nic"][u"xl710"]
+ elif u"x553" in test_name:
+ limit = plot[u"limits"][u"nic"][u"x553"]
+ elif u"cx556a" in test_name:
+ limit = plot[u"limits"][u"nic"][u"cx556a"]
+ elif u"e810cq" in test_name:
+ limit = plot[u"limits"][u"nic"][u"e810cq"]
+ else:
+ limit = 0
+ if limit > nic_limit:
+ nic_limit = limit
+
+ mul = 2 if u"ge2p" in test_name else 1
+ if u"10ge" in test_name:
+ limit = plot[u"limits"][u"link"][u"10ge"] * mul
+ elif u"25ge" in test_name:
+ limit = plot[u"limits"][u"link"][u"25ge"] * mul
+ elif u"40ge" in test_name:
+ limit = plot[u"limits"][u"link"][u"40ge"] * mul
+ elif u"100ge" in test_name:
+ limit = plot[u"limits"][u"link"][u"100ge"] * mul
+ else:
+ limit = 0
+ if limit > lnk_limit:
+ lnk_limit = limit
+
+ if u"cx556a" in test_name:
+ limit = plot[u"limits"][u"pci"][u"pci-g3-x8"]
+ else:
+ limit = plot[u"limits"][u"pci"][u"pci-g3-x16"]
+ if limit > pci_limit:
+ pci_limit = limit
+
+ traces = list()
+ annotations = list()
+ x_vals = [1, 2, 4]