report generation added for dynamic data

pick 0429552 conflicts resolved in lf_graph changes
This commit is contained in:
anil-tegala
2021-07-13 19:18:28 +05:30
parent d50ed322f5
commit bcbaff86e6
5 changed files with 378 additions and 450 deletions

View File

@@ -9,7 +9,7 @@ SETUP:
/lanforge/html-reports directory needs to be present or output generated in local file /lanforge/html-reports directory needs to be present or output generated in local file
EXAMPLE: EXAMPLE:
see: /py-scritps/lf_csv_test.py for example see: /py-scritps/lf_report_test.py for example
COPYWRITE COPYWRITE
Copyright 2021 Candela Technologies Inc Copyright 2021 Candela Technologies Inc
@@ -41,7 +41,7 @@ class LfCSV:
df[self.columns[i]] = self.rows[i] df[self.columns[i]] = self.rows[i]
csv_df = pd.DataFrame(df) csv_df = pd.DataFrame(df)
print(csv_df) print(csv_df)
csv_df.to_csv(self.filename, encoding='utf-8', na_rep='NA', float_format='%.2f') csv_df.to_csv(self.filename, index=False, encoding='utf-8', na_rep='NA', float_format='%.2f')
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -52,7 +52,7 @@ class lf_bar_graph():
_xticks_font = None, _xticks_font = None,
_grp_title = "", _grp_title = "",
_dpi=96, _dpi=96,
_enable_csv=True): _enable_csv=False):
self.data_set = _data_set self.data_set = _data_set
self.xaxis_name = _xaxis_name self.xaxis_name = _xaxis_name
@@ -304,11 +304,11 @@ class lf_horizontal_stacked_graph():
plt.savefig("%s.png" % self.graph_image_name, dpi=96) plt.savefig("%s.png" % self.graph_image_name, dpi=96)
plt.close() plt.close()
print("{}.png".format(self.graph_image_name)) print("{}.png".format(self.graph_image_name))
# if self.enable_csv: if self.enable_csv:
# self.lf_csv.columns = self.label self.lf_csv.columns = self.label
# self.lf_csv.rows = self.data_set self.lf_csv.rows = self.data_set
# self.lf_csv.filename = f"{self.graph_image_name}.csv" self.lf_csv.filename = f"{self.graph_image_name}.csv"
# self.lf_csv.generate_csv() self.lf_csv.generate_csv()
return "%s.png" % self.graph_image_name return "%s.png" % self.graph_image_name

View File

@@ -81,6 +81,7 @@ class lf_report():
self.footer_html = "" self.footer_html = ""
self.graph_titles="" self.graph_titles=""
self.graph_image="" self.graph_image=""
self.csv_file_name=""
self.html = "" self.html = ""
self.custom_html = "" self.custom_html = ""
self.objective = _obj self.objective = _obj
@@ -146,8 +147,13 @@ class lf_report():
print("graph_src_file: {}".format(graph_src_file)) print("graph_src_file: {}".format(graph_src_file))
print("graph_dst_file: {}".format(graph_dst_file)) print("graph_dst_file: {}".format(graph_dst_file))
shutil.move(graph_src_file, graph_dst_file) shutil.move(graph_src_file, graph_dst_file)
def move_csv_file(self): def move_csv_file(self):
csv_src_file = str(self.fil) csv_src_file = str(self.csv_file_name)
csv_dst_file = str(self.path_date_time)+'/'+str(self.csv_file_name)
print("csv_src_file: {}".format(csv_src_file))
print("csv_dst_file: {}".format(csv_dst_file))
shutil.move(csv_src_file, csv_dst_file)
def set_path(self,_path): def set_path(self,_path):
self.path = _path self.path = _path
@@ -187,6 +193,11 @@ class lf_report():
def set_graph_title(self,_graph_title): def set_graph_title(self,_graph_title):
self.graph_title = _graph_title self.graph_title = _graph_title
# sets the csv file name as graph title
def set_csv_filename(self, _graph_title):
fname, ext = os.path.splitext(_graph_title)
self.csv_file_name = fname + ".csv"
# The _date is set when class is enstanciated / created so this set_date should be used with caution, used to synchronize results # The _date is set when class is enstanciated / created so this set_date should be used with caution, used to synchronize results
def set_date(self,_date): def set_date(self,_date):
self.date = _date self.date = _date
@@ -275,7 +286,6 @@ class lf_report():
self.write_output_pdf = "{}/{}-{}".format(self.path_date_time,self.date,self.output_pdf) self.write_output_pdf = "{}/{}-{}".format(self.path_date_time,self.date,self.output_pdf)
pdfkit.from_file(self.write_output_html, self.write_output_pdf, options=options) pdfkit.from_file(self.write_output_html, self.write_output_pdf, options=options)
def generate_report(self): def generate_report(self):
self.write_html() self.write_html()
self.write_pdf() self.write_pdf()
@@ -351,7 +361,7 @@ class lf_report():
os.mkdir(self.path_date_time) os.mkdir(self.path_date_time)
def build_table(self): def build_table(self):
self.dataframe_html = self.dataframe.to_html(index=False, justify='left') # have the index be able to be passed in. self.dataframe_html = self.dataframe.to_html(index=False, justify='center') # have the index be able to be passed in.
self.html += self.dataframe_html self.html += self.dataframe_html
def test_setup_table(self,test_setup_data, value): def test_setup_table(self,test_setup_data, value):

View File

@@ -36,7 +36,7 @@ if __name__ == "__main__":
'radios': [1, 1, 2, 2, 6, 9, 3], 'radios': [1, 1, 2, 2, 6, 9, 3],
'MIMO': ['N', 'N', 'N', 'Y', 'Y', 'Y', 'Y'], 'MIMO': ['N', 'N', 'N', 'Y', 'Y', 'Y', 'Y'],
'stations': [200, 64, 200, 128, 384, 72, 192], 'stations': [200, 64, 200, 128, 384, 72, 192],
'mbps': [300, 300, 300, 10000, 10000, 10000, 10000] '1 mbps': [300, 300, 300, 10000, 10000, 10000, 10000]
}) })
print(dataframe) print(dataframe)

View File

@@ -57,7 +57,8 @@ class ThroughputQOS(Realm):
create_sta=True, create_sta=True,
name_prefix=None, name_prefix=None,
upstream=None, upstream=None,
radio="wiphy0", radio_2g="wiphy0",
radio_5g="wiphy1",
host="localhost", host="localhost",
port=8080, port=8080,
mode=0, mode=0,
@@ -69,7 +70,6 @@ class ThroughputQOS(Realm):
number_template="00000", number_template="00000",
test_duration="2m", test_duration="2m",
bands="2.4G, 5G, BOTH", bands="2.4G, 5G, BOTH",
radios="",
test_case={}, test_case={},
use_ht160=False, use_ht160=False,
_debug_on=False, _debug_on=False,
@@ -89,7 +89,8 @@ class ThroughputQOS(Realm):
self.ssid_5g = ssid_5g self.ssid_5g = ssid_5g
self.security_5g = security_5g self.security_5g = security_5g
self.password_5g = password_5g self.password_5g = password_5g
self.radio = radio.split(",") self.radio_2g = radio_2g
self.radio_5g = radio_5g
self.sta_list = sta_list self.sta_list = sta_list
self.create_sta = create_sta self.create_sta = create_sta
self.mode = mode self.mode = mode
@@ -98,7 +99,6 @@ class ThroughputQOS(Realm):
self.traffic_type = traffic_type self.traffic_type = traffic_type
self.tos = tos.split(",") self.tos = tos.split(",")
self.bands = bands.split(",") self.bands = bands.split(",")
self.radios = radios
self.test_case = test_case self.test_case = test_case
self.number_template = number_template self.number_template = number_template
self.debug = _debug_on self.debug = _debug_on
@@ -115,7 +115,7 @@ class ThroughputQOS(Realm):
self.station_profile.use_ht160 = use_ht160 self.station_profile.use_ht160 = use_ht160
if self.station_profile.use_ht160: if self.station_profile.use_ht160:
self.station_profile.mode = 9 self.station_profile.mode = 9
self.station_profile.mode = mode # self.station_profile.mode = mode
if self.ap is not None: if self.ap is not None:
self.station_profile.set_command_param("add_sta", "ap", self.ap) self.station_profile.set_command_param("add_sta", "ap", self.ap)
self.cx_profile.host = self.host self.cx_profile.host = self.host
@@ -127,15 +127,6 @@ class ThroughputQOS(Realm):
self.cx_profile.side_b_max_bps = side_b_max_rate self.cx_profile.side_b_max_bps = side_b_max_rate
def start(self, print_pass=False, print_fail=False): def start(self, print_pass=False, print_fail=False):
if self.create_sta:
self.station_profile.admin_up()
# check here if upstream port got IP
temp_stations = self.station_profile.station_names.copy()
if self.wait_for_ip(temp_stations):
self._pass("All stations got IPs")
else:
self._fail("Stations failed to get IPs")
self.exit_fail()
self.cx_profile.start_cx() self.cx_profile.start_cx()
def stop(self): def stop(self):
@@ -159,78 +150,62 @@ class ThroughputQOS(Realm):
for key in self.bands: for key in self.bands:
if self.create_sta: if self.create_sta:
if key == "2.4G" or key == "2.4g": if key == "2.4G" or key == "2.4g":
self.station_profile.mode = 11
if self.ssid is None: if self.ssid is None:
self.station_profile.use_security(self.security_2g, self.ssid_2g, self.password_2g) self.station_profile.use_security(self.security_2g, self.ssid_2g, self.password_2g)
else: else:
self.station_profile.use_security(self.security, self.ssid, self.password) self.station_profile.use_security(self.security, self.ssid, self.password)
if key == "5G" or key == "5g":
if self.ssid is None:
self.station_profile.use_security(self.security_5g, self.ssid_5g, self.password_5g)
else:
self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.set_number_template(self.number_template) self.station_profile.set_number_template(self.number_template)
print("Creating stations") print("Creating stations")
self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) self.station_profile.set_command_flag("add_sta", "create_admin_down", 1)
self.station_profile.set_command_param("set_port", "report_timer", 1500) self.station_profile.set_command_param("set_port", "report_timer", 1500)
self.station_profile.set_command_flag("set_port", "rpt_timer", 1) self.station_profile.set_command_flag("set_port", "rpt_timer", 1)
self.station_profile.create(radio=self.radio_2g, sta_names_=self.sta_list, debug=self.debug)
if key == "5G" or key == "5g":
self.station_profile.mode = 9
if self.ssid is None:
self.station_profile.use_security(self.security_5g, self.ssid_5g, self.password_5g)
else:
self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.set_number_template(self.number_template)
print("Creating stations")
self.station_profile.set_command_flag("add_sta", "create_admin_down", 1)
self.station_profile.set_command_param("set_port", "report_timer", 1500)
self.station_profile.set_command_flag("set_port", "rpt_timer", 1)
self.station_profile.create(radio=self.radio_5g, sta_names_=self.sta_list, debug=self.debug)
if key == "BOTH" or key == "both": if key == "BOTH" or key == "both":
keys = list(self.test_case.keys())
if "BOTH" in self.test_case:
self.radios = self.test_case["BOTH"].split(",")
elif "both" in self.test_case:
self.radios = self.test_case["both"].split(",")
split = len(self.sta_list) // 2 split = len(self.sta_list) // 2
if keys[0] == "2.4G" or keys[0] == "2.4g":
if self.ssid is None: if self.ssid is None:
self.station_profile.use_security(self.security_2g, self.ssid_2g, self.password_2g) self.station_profile.use_security(self.security_2g, self.ssid_2g, self.password_2g)
else: else:
self.station_profile.use_security(self.security, self.ssid, self.password) self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.mode = 11 self.station_profile.mode = 11
self.station_profile.create(radio=self.radios[0], sta_names_=self.sta_list[:split], self.station_profile.set_number_template(self.number_template)
print("Creating stations")
self.station_profile.set_command_flag("add_sta", "create_admin_down", 1)
self.station_profile.set_command_param("set_port", "report_timer", 1500)
self.station_profile.set_command_flag("set_port", "rpt_timer", 1)
self.station_profile.create(radio=self.radio_2g, sta_names_=self.sta_list[:split],
debug=self.debug) debug=self.debug)
if self.ssid is None: if self.ssid is None:
self.station_profile.use_security(self.security_5g, self.ssid_5g, self.password_5g) self.station_profile.use_security(self.security_5g, self.ssid_5g, self.password_5g)
else: else:
self.station_profile.use_security(self.security, self.ssid, self.password) self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.mode = 9 self.station_profile.mode = 9
self.station_profile.create(radio=self.radios[1], sta_names_=self.sta_list[split:], self.station_profile.set_number_template(self.number_template)
self.station_profile.set_command_flag("add_sta", "create_admin_down", 1)
self.station_profile.set_command_param("set_port", "report_timer", 1500)
self.station_profile.set_command_flag("set_port", "rpt_timer", 1)
self.station_profile.create(radio=self.radio_5g, sta_names_=self.sta_list[split:],
debug=self.debug) debug=self.debug)
elif keys[0] == "5G" or keys[0] == "5g": self.station_profile.admin_up()
if self.ssid is None: # check here if upstream port got IP
self.station_profile.use_security(self.security_5g, self.ssid_5g, self.password_5g) temp_stations = self.station_profile.station_names.copy()
if self.wait_for_ip(temp_stations):
self._pass("All stations got IPs")
else: else:
self.station_profile.use_security(self.security, self.ssid, self.password) self._fail("Stations failed to get IPs")
self.station_profile.mode = 9 self.exit_fail()
self.station_profile.create(radio=self.radios[0], sta_names_=self.sta_list[:split],
debug=self.debug)
if self.ssid is None:
self.station_profile.use_security(self.security_2g, self.ssid_2g, self.password_2g)
else:
self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.mode = 11
self.station_profile.create(radio=self.radios[1], sta_names_=self.sta_list[split:],
debug=self.debug)
else:
if self.ssid is None:
self.station_profile.use_security(self.security_2g, self.ssid_2g, self.password_2g)
else:
self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.mode = 11
self.station_profile.create(radio=self.radios[0], sta_names_=self.sta_list[:split],
debug=self.debug)
if self.ssid is None:
self.station_profile.use_security(self.security_5g, self.ssid_5g, self.password_5g)
else:
self.station_profile.use_security(self.security, self.ssid, self.password)
self.station_profile.mode = 9
self.station_profile.create(radio=self.radios[1], sta_names_=self.sta_list[split:],
debug=self.debug)
else:
self.station_profile.create(radio=self.radio[0], sta_names_=self.sta_list, debug=self.debug)
self._pass("PASS: Station build finished") self._pass("PASS: Station build finished")
self.create_cx() self.create_cx()
print("cx build finished") print("cx build finished")
@@ -248,11 +223,12 @@ class ThroughputQOS(Realm):
sleep_time=0, tos=ip_tos) sleep_time=0, tos=ip_tos)
print("cross connections with TOS type created.") print("cross connections with TOS type created.")
def evaluate_throughput(self): def evaluate_qos(self):
global case case = ""
tos_download = {'video': [], 'voice': [], 'bk': [], 'be': []} tos_download = {'video': [], 'voice': [], 'bk': [], 'be': []}
tx_b = {'bk': [], 'be': [], 'video': [], 'voice': []} tx_b = {'bk': [], 'be': [], 'video': [], 'voice': []}
rx_a = {'bk': [], 'be': [], 'video': [], 'voice': []} rx_a = {'bk': [], 'be': [], 'video': [], 'voice': []}
delay = {'bk': [], 'be': [], 'video': [], 'voice': []}
pkt_loss = {} pkt_loss = {}
tx_endps = {} tx_endps = {}
rx_endps = {} rx_endps = {}
@@ -261,10 +237,9 @@ class ThroughputQOS(Realm):
elif int(self.cx_profile.side_a_min_bps) != 0: elif int(self.cx_profile.side_a_min_bps) != 0:
case = str(int(self.cx_profile.side_a_min_bps) // 1000000) case = str(int(self.cx_profile.side_a_min_bps) // 1000000)
if len(self.cx_profile.created_cx.keys()) > 0: if len(self.cx_profile.created_cx.keys()) > 0:
endp_data = self.json_get('endp/all?fields=name,tx+pkts+ll,rx+pkts+ll') endp_data = self.json_get('endp/all?fields=name,tx+pkts+ll,rx+pkts+ll,delay')
endp_data.pop("handler") endp_data.pop("handler")
endp_data.pop("uri") endp_data.pop("uri")
print(endp_data)
endps = endp_data['endpoint'] endps = endp_data['endpoint']
for i in range(len(endps)): for i in range(len(endps)):
if i < len(endps) // 2: if i < len(endps) // 2:
@@ -279,44 +254,56 @@ class ThroughputQOS(Realm):
f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}")) f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}"))
tx_b['bk'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}")) tx_b['bk'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}"))
rx_a['bk'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}")) rx_a['bk'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}"))
delay['bk'].append(int(f"{rx_endps['%s-A' % sta]['delay']}"))
else: else:
tos_download['bk'].append(float(0)) tos_download['bk'].append(float(0))
tx_b['bk'].append(int(0)) tx_b['bk'].append(int(0))
rx_a['bk'].append(int(0)) rx_a['bk'].append(int(0))
delay['bk'].append(int(0))
elif temp % 4 == 1: elif temp % 4 == 1:
if int(self.cx_profile.side_b_min_bps) != 0: if int(self.cx_profile.side_b_min_bps) != 0:
tos_download['be'].append(float( tos_download['be'].append(float(
f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}")) f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}"))
tx_b['be'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}")) tx_b['be'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}"))
rx_a['be'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}")) rx_a['be'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}"))
delay['be'].append(int(f"{rx_endps['%s-A' % sta]['delay']}"))
else: else:
tos_download['be'].append(float(0)) tos_download['be'].append(float(0))
tx_b['be'].append(int(0)) tx_b['be'].append(int(0))
rx_a['be'].append(int(0)) rx_a['be'].append(int(0))
delay['be'].append(int(0))
elif temp % 4 == 2: elif temp % 4 == 2:
if int(self.cx_profile.side_b_min_bps) != 0: if int(self.cx_profile.side_b_min_bps) != 0:
tos_download['voice'].append(float( tos_download['voice'].append(float(
f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}")) f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}"))
tx_b['voice'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}")) tx_b['voice'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}"))
rx_a['voice'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}")) rx_a['voice'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}"))
delay['voice'].append(int(f"{rx_endps['%s-A' % sta]['delay']}"))
else: else:
tos_download['voice'].append(float(0)) tos_download['voice'].append(float(0))
tx_b['voice'].append(int(0)) tx_b['voice'].append(int(0))
rx_a['voice'].append(int(0)) rx_a['voice'].append(int(0))
delay['voice'].append(int(0))
elif temp % 4 == 3: elif temp % 4 == 3:
if int(self.cx_profile.side_b_min_bps) != 0: if int(self.cx_profile.side_b_min_bps) != 0:
tos_download['video'].append(float( tos_download['video'].append(float(
f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}")) f"{list((self.json_get('/cx/%s?fields=bps+rx+a' % sta)).values())[2]['bps rx a'] / 1000000:.2f}"))
tx_b['video'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}")) tx_b['video'].append(int(f"{tx_endps['%s-B' % sta]['tx pkts ll']}"))
rx_a['video'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}")) rx_a['video'].append(int(f"{rx_endps['%s-A' % sta]['rx pkts ll']}"))
delay['video'].append(int(f"{rx_endps['%s-A' % sta]['delay']}"))
else: else:
tos_download['video'].append(float(0)) tos_download['video'].append(float(0))
tx_b['video'].append(int(0)) tx_b['video'].append(int(0))
rx_a['video'].append(int(0)) rx_a['video'].append(int(0))
delay['video'].append(int(0))
tos_download.update({"bkQOS": float(f"{sum(tos_download['bk']):.2f}")}) tos_download.update({"bkQOS": float(f"{sum(tos_download['bk']):.2f}")})
tos_download.update({"beQOS": float(f"{sum(tos_download['be']):.2f}")}) tos_download.update({"beQOS": float(f"{sum(tos_download['be']):.2f}")})
tos_download.update({"videoQOS": float(f"{sum(tos_download['video']):.2f}")}) tos_download.update({"videoQOS": float(f"{sum(tos_download['video']):.2f}")})
tos_download.update({"voiceQOS": float(f"{sum(tos_download['voice']):.2f}")}) tos_download.update({"voiceQOS": float(f"{sum(tos_download['voice']):.2f}")})
tos_download.update({"bkDELAY": float(f"{sum(delay['bk']) / 1000:.2f}")})
tos_download.update({"beDELAY": float(f"{sum(delay['be']) / 1000:.2f}")})
tos_download.update({"videoDELAY": float(f"{sum(delay['video']) / 1000:.2f}")})
tos_download.update({"voiceDELAY": float(f"{sum(delay['voice']) / 1000:.2f}")})
if sum(tx_b['bk']) != 0 or sum(tx_b['be']) != 0 or sum(tx_b['video']) != 0 or sum(tx_b['voice']) != 0: if sum(tx_b['bk']) != 0 or sum(tx_b['be']) != 0 or sum(tx_b['video']) != 0 or sum(tx_b['voice']) != 0:
tos_download.update( tos_download.update(
{"bkLOSS": float(f"{((sum(tx_b['bk']) - sum(rx_a['bk'])) / sum(tx_b['bk'])) * 100:.2f}")}) {"bkLOSS": float(f"{((sum(tx_b['bk']) - sum(rx_a['bk'])) / sum(tx_b['bk'])) * 100:.2f}")})
@@ -328,21 +315,66 @@ class ThroughputQOS(Realm):
f"{((sum(tx_b['voice']) - sum(rx_a['voice'])) / sum(tx_b['voice'])) * 100:.2f}")}) f"{((sum(tx_b['voice']) - sum(rx_a['voice'])) / sum(tx_b['voice'])) * 100:.2f}")})
tos_download.update({'tx_b': tx_b}) tos_download.update({'tx_b': tx_b})
tos_download.update({'rx_a': rx_a}) tos_download.update({'rx_a': rx_a})
tos_download.update({'delay': delay})
else: else:
print("no RX values available to evaluate QOS") print("no RX values available to evaluate QOS")
key = case + " " + "Mbps" key = case + " " + "Mbps"
print(tos_download)
return {key: tos_download} return {key: tos_download}
def generate_report(self, data, test_setup_info, input_setup_info): def set_report_data(self, data):
print(data) print(data)
res = {} res = {}
if data is not None: if data is not None:
for i in range(len(data)): for i in range(len(data)):
res.update(data[i]) res.update({self.test_case[i]: data[i]})
else: else:
print("No Data found to generate report!") print("No Data found to generate report!")
exit(1) exit(1)
if self.test_case is not None:
table_df = {}
num_stations = []
throughput = []
graph_df = {}
for case in self.test_case:
throughput_df = [[], [], [], []]
pkt_loss_df = [[], [], [], []]
latency_df = [[], [], [], []]
if case == "2.4g" or case == "2.4G":
num_stations.append("{} - bgn-AC".format(str(len(self.sta_list))))
elif case == "5g" or case == "5G":
num_stations.append("{} - an-AC".format(str(len(self.sta_list))))
elif case == "both" or case == "BOTH":
num_stations.append(
"{} - bgn-AC + {} - an-AC ".format(str(len(self.sta_list) // 2), str(len(self.sta_list) // 2)))
for key in res[case]:
throughput.append(
"BK : {}, BE : {}, VI: {}, VO: {}".format(res[case][key]["bkQOS"],
res[case][key]["beQOS"],
res[case][key][
"videoQOS"],
res[case][key][
"voiceQOS"]))
throughput_df[0].append(res[case][key]['bkQOS'])
throughput_df[1].append(res[case][key]['beQOS'])
throughput_df[2].append(res[case][key]['videoQOS'])
throughput_df[3].append(res[case][key]['voiceQOS'])
pkt_loss_df[0].append(res[case][key]['bkLOSS'])
pkt_loss_df[1].append(res[case][key]['beLOSS'])
pkt_loss_df[2].append(res[case][key]['videoLOSS'])
pkt_loss_df[3].append(res[case][key]['voiceLOSS'])
latency_df[0].append(res[case][key]['bkDELAY'])
latency_df[1].append(res[case][key]['beDELAY'])
latency_df[2].append(res[case][key]['videoDELAY'])
latency_df[3].append(res[case][key]['voiceDELAY'])
table_df.update({"No of Stations": num_stations})
table_df.update({"Throughput for Load {}".format(key): throughput})
graph_df.update({case: [throughput_df, pkt_loss_df, latency_df]})
res.update({"throughput_table_df": table_df})
res.update({"graph_df": graph_df})
return res
def generate_report(self, data, test_setup_info, input_setup_info):
res = self.set_report_data(data)
report = lf_report(_output_pdf="throughput_qos.pdf", _output_html="throughput_qos.html") report = lf_report(_output_pdf="throughput_qos.pdf", _output_html="throughput_qos.html")
report_path = report.get_path() report_path = report.get_path()
report_path_date_time = report.get_path_date_time() report_path_date_time = report.get_path_date_time()
@@ -355,271 +387,202 @@ class ThroughputQOS(Realm):
_obj="Through this test we can evaluate the throughput for given number of clients which" _obj="Through this test we can evaluate the throughput for given number of clients which"
" runs the traffic with a particular Type of Service i.e BK,BE,VI,VO") " runs the traffic with a particular Type of Service i.e BK,BE,VI,VO")
report.build_objective() report.build_objective()
report.set_custom_html(_custom_html=self.test_setup_information(test_setup_data=test_setup_info, report.test_setup_table(test_setup_data=test_setup_info, value="Device Under Test")
colmn="Device Under Test"))
report.build_custom()
report.set_table_title( report.set_table_title(
"Overall download Throughput for all TOS i.e BK | BE | Video (VI) | Voice (VO) in 2.4Ghz") "Overall download Throughput for all TOS i.e BK | BE | Video (VI) | Voice (VO)")
report.build_table_title() report.build_table_title()
df_throughput = pd.DataFrame(res["throughput_table_df"])
table_df = [[], [], [], [], []]
pkt_loss = [[], [], [], [], []]
for key in res:
if key == '1 Mbps':
table_df[0].append(res[key]['bkQOS'])
table_df[0].append(res[key]['beQOS'])
table_df[0].append(res[key]['videoQOS'])
table_df[0].append(res[key]['voiceQOS'])
pkt_loss[0].append(res[key]['bkLOSS'])
pkt_loss[0].append(res[key]['beLOSS'])
pkt_loss[0].append(res[key]['videoLOSS'])
pkt_loss[0].append(res[key]['voiceLOSS'])
if key == '2 Mbps':
table_df[1].append(res[key]['bkQOS'])
table_df[1].append(res[key]['beQOS'])
table_df[1].append(res[key]['videoQOS'])
table_df[1].append(res[key]['voiceQOS'])
pkt_loss[1].append(res[key]['bkLOSS'])
pkt_loss[1].append(res[key]['beLOSS'])
pkt_loss[1].append(res[key]['videoLOSS'])
pkt_loss[1].append(res[key]['voiceLOSS'])
if key == '3 Mbps':
table_df[2].append(res[key]['bkQOS'])
table_df[2].append(res[key]['beQOS'])
table_df[2].append(res[key]['videoQOS'])
table_df[2].append(res[key]['voiceQOS'])
pkt_loss[2].append(res[key]['bkLOSS'])
pkt_loss[2].append(res[key]['beLOSS'])
pkt_loss[2].append(res[key]['videoLOSS'])
pkt_loss[2].append(res[key]['voiceLOSS'])
if key == '4 Mbps':
table_df[3].append(res[key]['bkQOS'])
table_df[3].append(res[key]['beQOS'])
table_df[3].append(res[key]['videoQOS'])
table_df[3].append(res[key]['voiceQOS'])
pkt_loss[3].append(res[key]['bkLOSS'])
pkt_loss[3].append(res[key]['beLOSS'])
pkt_loss[3].append(res[key]['videoLOSS'])
pkt_loss[3].append(res[key]['voiceLOSS'])
if key == '5 Mbps':
table_df[4].append(res[key]['bkQOS'])
table_df[4].append(res[key]['beQOS'])
table_df[4].append(res[key]['videoQOS'])
table_df[4].append(res[key]['voiceQOS'])
pkt_loss[4].append(res[key]['bkLOSS'])
pkt_loss[4].append(res[key]['beLOSS'])
pkt_loss[4].append(res[key]['videoLOSS'])
pkt_loss[4].append(res[key]['voiceLOSS'])
table_df2 = []
for i in range(len(table_df)):
table_df2.append(
f'BK: {table_df[i][0]} | BE: {table_df[i][1]} | VI: {table_df[i][2]} | VO: {table_df[i][3]}')
df_throughput = pd.DataFrame({
'Mode': ['bgn-AC'], "No.of.clients": [len(self.sta_list)],
'Throughput for Load (1 Mbps)': [table_df2[0]],
'Throughput for Load (2 Mbps)': [table_df2[1]],
'Throughput for Load (3 Mbps)': [table_df2[2]],
'Throughput for Load (4 Mbps)': [table_df2[3]],
'Throughput for Load (5 Mbps)': [table_df2[4]],
})
report.set_table_dataframe(df_throughput) report.set_table_dataframe(df_throughput)
report.build_table() report.build_table()
graph_df = [[], [], [], []] for key in res["graph_df"]:
pkt_loss_df = [[], [], [], []] report.set_graph_title(f"Overall Download throughput for {len(self.sta_list)} - {key} clients with different TOS.")
for key in res:
if key == '1 Mbps':
graph_df[0].append(res[key]['bkQOS'])
graph_df[1].append(res[key]['beQOS'])
graph_df[2].append(res[key]['videoQOS'])
graph_df[3].append(res[key]['voiceQOS'])
pkt_loss_df[0].append(res[key]['bkLOSS'])
pkt_loss_df[1].append(res[key]['beLOSS'])
pkt_loss_df[2].append(res[key]['videoLOSS'])
pkt_loss_df[3].append(res[key]['voiceLOSS'])
if key == '2 Mbps':
graph_df[0].append(res[key]['bkQOS'])
graph_df[1].append(res[key]['beQOS'])
graph_df[2].append(res[key]['videoQOS'])
graph_df[3].append(res[key]['voiceQOS'])
pkt_loss_df[0].append(res[key]['bkLOSS'])
pkt_loss_df[1].append(res[key]['beLOSS'])
pkt_loss_df[2].append(res[key]['videoLOSS'])
pkt_loss_df[3].append(res[key]['voiceLOSS'])
if key == '3 Mbps':
graph_df[0].append(res[key]['bkQOS'])
graph_df[1].append(res[key]['beQOS'])
graph_df[2].append(res[key]['videoQOS'])
graph_df[3].append(res[key]['voiceQOS'])
pkt_loss_df[0].append(res[key]['bkLOSS'])
pkt_loss_df[1].append(res[key]['beLOSS'])
pkt_loss_df[2].append(res[key]['videoLOSS'])
pkt_loss_df[3].append(res[key]['voiceLOSS'])
if key == '4 Mbps':
graph_df[0].append(res[key]['bkQOS'])
graph_df[1].append(res[key]['beQOS'])
graph_df[2].append(res[key]['videoQOS'])
graph_df[3].append(res[key]['voiceQOS'])
pkt_loss_df[0].append(res[key]['bkLOSS'])
pkt_loss_df[1].append(res[key]['beLOSS'])
pkt_loss_df[2].append(res[key]['videoLOSS'])
pkt_loss_df[3].append(res[key]['voiceLOSS'])
if key == '5 Mbps':
graph_df[0].append(res[key]['bkQOS'])
graph_df[1].append(res[key]['beQOS'])
graph_df[2].append(res[key]['videoQOS'])
graph_df[3].append(res[key]['voiceQOS'])
pkt_loss_df[0].append(res[key]['bkLOSS'])
pkt_loss_df[1].append(res[key]['beLOSS'])
pkt_loss_df[2].append(res[key]['videoLOSS'])
pkt_loss_df[3].append(res[key]['voiceLOSS'])
report.set_graph_title(f"Overall Download throughput for all {self.bands[0]} clients with different TOS.")
report.set_obj_html(_obj_title="", _obj="The below graph represents overall download throughput for all " report.set_obj_html(_obj_title="", _obj="The below graph represents overall download throughput for all "
"connected stations running BK, BE, VO, VI traffic with different " "connected stations running BK, BE, VO, VI traffic with different "
"intended loads per station 1 Mbps, 2 Mbps, 3 Mbps, 4 Mbps, 5 Mbps.") "intended loads per station {}".format(res["graph_df"][key].keys()))
report.build_graph_title() report.build_graph_title()
report.build_objective() report.build_objective()
graph = lf_bar_graph(_data_set=graph_df, graph = lf_bar_graph(_data_set=res["graph_df"][key][0],
_xaxis_name="Load per Type of Service", _xaxis_name="Load per Type of Service",
_yaxis_name="Throughput (Mbps)", _yaxis_name="Throughput (Mbps)",
_xaxis_categories=[1, 2, 3, 4, 5, 6], _xaxis_categories=[1],
_xaxis_label=['1 Mbps', '2 Mbps', '3 Mbps', '4 Mbps', '5 Mbps'], _xaxis_label=['1 Mbps', '2 Mbps', '3 Mbps', '4 Mbps', '5 Mbps'],
_graph_image_name=f"tos_download_{self.bands[0]}Hz", _graph_image_name=f"tos_download_{key}Hz",
_label=["BK", "BE", "VI", "VO"], _label=["BK", "BE", "VI", "VO"],
_step_size=1, _xaxis_step=1,
_graph_title="Overall download throughput BK,BE,VO,VI traffic streams", _graph_title="Overall download throughput BK,BE,VO,VI traffic streams",
_title_size=16, _title_size=16,
_color=['orangered', 'greenyellow', 'steelblue', 'blueviolet'], _color=['orangered', 'greenyellow', 'steelblue', 'blueviolet'],
_color_edge='black', _color_edge='black',
_bar_width=0.15, _bar_width=0.15,
_dpi=96, _dpi=96,
_enable_csv=True,
_color_name=['orangered', 'greenyellow', 'steelblue', 'blueviolet']) _color_name=['orangered', 'greenyellow', 'steelblue', 'blueviolet'])
graph_png = graph.build_bar_graph() graph_png = graph.build_bar_graph()
print("graph name {}".format(graph_png)) print("graph name {}".format(graph_png))
report.set_graph_image(graph_png) report.set_graph_image(graph_png)
# need to move the graph image to the results # need to move the graph image to the results directory
report.move_graph_image() report.move_graph_image()
report.set_csv_filename(graph_png)
report.move_csv_file()
report.build_graph() report.build_graph()
report.set_graph_title(f"Overall Packet loss for all {self.bands[0]} clients with different TOS.") report.set_graph_title(f"Overall Packet loss for {len(self.sta_list)} - {key} clients with different TOS.")
report.set_obj_html(_obj_title="", _obj="This graph shows the overall packet loss for the connected stations " report.set_obj_html(_obj_title="",
"for BK,BE,VO,VI traffic with intended load per station 1 Mbps, " _obj="This graph shows the overall packet loss for the connected stations "
"2 Mbps, 3 Mbps, 4 Mbps, 5 Mbps") "for BK,BE,VO,VI traffic with intended load per station {}".format(res["graph_df"][key].keys()))
report.build_graph_title() report.build_graph_title()
report.build_objective() report.build_objective()
graph = lf_bar_graph(_data_set=pkt_loss_df, graph = lf_bar_graph(_data_set=res["graph_df"][key][1],
_xaxis_name="Load per Type of Service", _xaxis_name="Load per Type of Service",
_yaxis_name="Packet Loss (%)", _yaxis_name="Packet Loss (%)",
_xaxis_categories=[1, 2, 3, 4, 5, 6], _xaxis_categories=[1],
_xaxis_label=['1 Mbps', '2 Mbps', '3 Mbps', '4 Mbps', '5 Mbps'], _xaxis_label=['1 Mbps', '2 Mbps', '3 Mbps', '4 Mbps', '5 Mbps'],
_graph_image_name=f"pkt_loss_{self.bands[0]}Hz", _graph_image_name=f"pkt_loss_{key}Hz",
_label=["BK", "BE", "VI", "VO"], _label=["BK", "BE", "VI", "VO"],
_step_size=1, _xaxis_step=1,
_graph_title="Load vs Packet Loss", _graph_title="Load vs Packet Loss",
_title_size=16, _title_size=16,
_color=['orangered', 'greenyellow', 'steelblue', 'blueviolet'], _color=['orangered', 'greenyellow', 'steelblue', 'blueviolet'],
_color_edge='black', _color_edge='black',
_bar_width=0.15, _bar_width=0.15,
_dpi=96, _dpi=96,
_enable_csv=True,
_color_name=['orangered', 'greenyellow', 'steelblue', 'blueviolet']) _color_name=['orangered', 'greenyellow', 'steelblue', 'blueviolet'])
graph_png = graph.build_bar_graph() graph_png = graph.build_bar_graph()
print("graph name {}".format(graph_png)) print("graph name {}".format(graph_png))
report.set_graph_image(graph_png) report.set_graph_image(graph_png)
# need to move the graph image to the results # need to move the graph image to the results directory
report.move_graph_image() report.move_graph_image()
report.set_csv_filename(graph_png)
report.move_csv_file()
report.build_graph() report.build_graph()
self.generate_individual_graph(data, report) report.set_obj_html(
report.set_custom_html(_custom_html=self.test_setup_information(test_setup_data=input_setup_info, colmn="Information")) _obj_title=f"Overall Latency for {len(self.sta_list)} - {key} clients with different TOS.",
_obj="This graph shows the overall Latency for the connected stations "
"for BK,BE,VO,VI traffic with intended load per station {}".format(res["graph_df"][key].keys()))
report.build_objective()
graph = lf_bar_graph(_data_set=res["graph_df"][key][2],
_xaxis_name="Load per Type of Service",
_yaxis_name="Average Latency (in seconds)",
_xaxis_categories=[1],
_xaxis_label=['1 Mbps', '2 Mbps', '3 Mbps', '4 Mbps', '5 Mbps'],
_graph_image_name=f"latency_{key}Hz",
_label=["BK", "BE", "VI", "VO"],
_xaxis_step=1,
_graph_title="Overall Download Latency BK,BE,VO,VI traffic streams",
_title_size=16,
_show_bar_value=True,
_color=['orangered', 'yellowgreen', 'steelblue', 'blueviolet'],
_color_edge='black',
_bar_width=0.15,
_dpi=96,
_enable_csv=True,
_color_name=['orangered', 'yellowgreen', 'steelblue', 'blueviolet'])
graph_png = graph.build_bar_graph()
print("graph name {}".format(graph_png))
report.set_graph_image(graph_png)
# need to move the graph image to the results directory
report.move_graph_image()
report.set_csv_filename(graph_png)
report.move_csv_file()
report.build_graph()
self.generate_individual_graph(res, report)
report.test_setup_table(test_setup_data=input_setup_info, value="Information")
report.build_custom() report.build_custom()
report.write_html() report.write_html()
report.write_pdf() report.write_pdf()
def generate_individual_graph(self, data, report): def generate_individual_graph(self, res, report):
if data is not None:
res = {}
for i in range(len(data)):
res.update(data[i])
if len(res.keys()) > 0: if len(res.keys()) > 0:
count = 1 if "throughput_table_df" in res:
res.pop("throughput_table_df")
if "graph_df" in res:
res.pop("graph_df")
for key in res: for key in res:
report.set_graph_title( for load in res[key]:
_graph_title=f"Individual download throughput with intended load {key}/station for traffic BK(WiFi).") report.set_obj_html(
report.set_obj_html(_obj_title="", _obj_title=f"Individual download throughput with intended load {load}/station for traffic BK(WiFi).",
_obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running BK " _obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running BK "
f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows “" f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows “"
f"Throughput in Mbps”.") f"Throughput in Mbps”.")
report.build_graph_title()
report.build_objective() report.build_objective()
graph = lf_bar_graph(_data_set=[res[key]['bk']], _xaxis_name="Clients running - BK", graph = lf_bar_graph(_data_set=[res[key][load]['bk']], _xaxis_name="Clients running - BK",
_yaxis_name="Throughput in Mbps", _yaxis_name="Throughput in Mbps",
_xaxis_categories=[i + 1 for i in range(len(self.sta_list))], _xaxis_categories=[i + 1 for i in range(len(self.sta_list))],
_xaxis_label=[i + 1 for i in range(len(self.sta_list))], _xaxis_label=[i + 1 for i in range(len(self.sta_list))],
_label=["BK"], _label=["BK"],
_step_size=1, _xaxis_step=1,
_xticks_font=8, _xticks_font=8,
_graph_title="Individual download throughput for BK(WIFI) traffic - {} clients".format(self.bands[0]), _graph_title="Individual download throughput for BK(WIFI) traffic - {} clients".format(
key),
_title_size=16, _title_size=16,
_bar_width=0.15, _color_name=['orangered'], _bar_width=0.15, _color_name=['orangered'],
_graph_image_name="{}_bk_{}".format(self.bands[0], count), _color_edge=['black'], _enable_csv=True,
_graph_image_name="{}_bk_{}".format(key, load), _color_edge=['black'],
_color=['orangered']) _color=['orangered'])
graph_png = graph.build_bar_graph() graph_png = graph.build_bar_graph()
print("graph name {}".format(graph_png)) print("graph name {}".format(graph_png))
report.set_graph_image(graph_png) report.set_graph_image(graph_png)
# need to move the graph image to the results # need to move the graph image to the results
report.move_graph_image() report.move_graph_image()
report.set_csv_filename(graph_png)
report.move_csv_file()
report.build_graph() report.build_graph()
report.set_graph_title( report.set_obj_html(
_graph_title=f"Individual download throughput with intended load {key}/station for traffic BE(WiFi).") _obj_title=f"Individual download throughput with intended load {load}/station for traffic BE(WiFi).",
report.set_obj_html(_obj_title="",
_obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running BE " _obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running BE "
f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows " f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows "
f"“Throughput in Mbps”.") f"“Throughput in Mbps”.")
report.build_graph_title()
report.build_objective() report.build_objective()
graph = lf_bar_graph(_data_set=[res[key]['be']], _xaxis_name="Clients running - BE", graph = lf_bar_graph(_data_set=[res[key][load]['be']], _xaxis_name="Clients running - BE",
_yaxis_name="Throughput in Mbps", _yaxis_name="Throughput in Mbps",
_xaxis_categories=[i + 1 for i in range(len(self.sta_list))], _xaxis_categories=[i + 1 for i in range(len(self.sta_list))],
_xaxis_label=[i + 1 for i in range(len(self.sta_list))], _xaxis_label=[i + 1 for i in range(len(self.sta_list))],
_label=["BE"], _label=["BE"],
_step_size=1, _xaxis_step=1,
_xticks_font=8, _xticks_font=8,
_graph_title="Individual download throughput for BE(WIFI) traffic - {} clients".format(self.bands[0]), _graph_title="Individual download throughput for BE(WIFI) traffic - {} clients".format(
key),
_title_size=16, _title_size=16,
_bar_width=0.15, _color_name=['greenyellow'], _bar_width=0.15, _color_name=['yellowgreen'],
_graph_image_name="{}_be_{}".format(self.bands[0], count), _color_edge=['black'], _enable_csv=True,
_color=['greenyellow']) _graph_image_name="{}_be_{}".format(key, load), _color_edge=['black'],
_color=['yellowgreen'])
graph_png = graph.build_bar_graph() graph_png = graph.build_bar_graph()
print("graph name {}".format(graph_png)) print("graph name {}".format(graph_png))
report.set_graph_image(graph_png) report.set_graph_image(graph_png)
# need to move the graph image to the results # need to move the graph image to the results
report.move_graph_image() report.move_graph_image()
report.set_csv_filename(graph_png)
report.move_csv_file()
report.build_graph() report.build_graph()
report.set_graph_title( report.set_obj_html(
_graph_title=f"Individual download throughput with intended load {key}/station for traffic VI(WiFi).") _obj_title=f"Individual download throughput with intended load {load}/station for traffic VI(WiFi).",
report.set_obj_html(_obj_title="",
_obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running VI " _obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running VI "
f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows " f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows "
f"“Throughput in Mbps”.") f"“Throughput in Mbps”.")
report.build_graph_title()
report.build_objective() report.build_objective()
graph = lf_bar_graph(_data_set=[res[key]['video']], _xaxis_name="Clients running - VI", graph = lf_bar_graph(_data_set=[res[key][load]['video']], _xaxis_name="Clients running - VI",
_yaxis_name="Throughput in Mbps", _yaxis_name="Throughput in Mbps",
_xaxis_categories=[i + 1 for i in range(len(self.sta_list))], _xaxis_categories=[i + 1 for i in range(len(self.sta_list))],
_xaxis_label=[i + 1 for i in range(len(self.sta_list))], _xaxis_label=[i + 1 for i in range(len(self.sta_list))],
_label=["Video"], _label=["Video"],
_step_size=1, _xaxis_step=1,
_xticks_font=8, _xticks_font=8,
_graph_title="Individual download throughput for VI(WIFI) traffic - {} clients".format(self.bands[0]), _graph_title="Individual download throughput for VI(WIFI) traffic - {} clients".format(
key),
_title_size=16, _title_size=16,
_bar_width=0.15, _color_name=['steelblue'], _bar_width=0.15, _color_name=['steelblue'],
_graph_image_name="{}_video_{}".format(self.bands[0], count), _enable_csv=True,
_graph_image_name="{}_video_{}".format(key, load),
_color_edge=['black'], _color_edge=['black'],
_color=['steelblue']) _color=['steelblue'])
graph_png = graph.build_bar_graph() graph_png = graph.build_bar_graph()
@@ -627,26 +590,28 @@ class ThroughputQOS(Realm):
report.set_graph_image(graph_png) report.set_graph_image(graph_png)
# need to move the graph image to the results # need to move the graph image to the results
report.move_graph_image() report.move_graph_image()
report.set_csv_filename(graph_png)
report.move_csv_file()
report.build_graph() report.build_graph()
report.set_graph_title( report.set_obj_html(
_graph_title=f"Individual download throughput with intended load {key}/station for traffic VO(WiFi).") _obj_title=f"Individual download throughput with intended load {load}/station for traffic VO(WiFi).",
report.set_obj_html(_obj_title="",
_obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running VO " _obj=f"The below graph represents individual throughput for {len(self.sta_list)} clients running VO "
f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows " f"(WiFi) traffic. X- axis shows “number of clients” and Y-axis shows "
f"“Throughput in Mbps”.") f"“Throughput in Mbps”.")
report.build_graph_title()
report.build_objective() report.build_objective()
graph = lf_bar_graph(_data_set=[res[key]['voice']], _xaxis_name="Clients running - VO", graph = lf_bar_graph(_data_set=[res[key][load]['voice']], _xaxis_name="Clients running - VO",
_yaxis_name="Throughput in Mbps", _yaxis_name="Throughput in Mbps",
_xaxis_categories=[i + 1 for i in range(len(self.sta_list))], _xaxis_categories=[i + 1 for i in range(len(self.sta_list))],
_xaxis_label=[i + 1 for i in range(len(self.sta_list))], _xaxis_label=[i + 1 for i in range(len(self.sta_list))],
_label=['Voice'], _label=['Voice'],
_step_size=1, _xaxis_step=1,
_xticks_font=8, _xticks_font=8,
_graph_title="Individual download throughput for VO(WIFI) traffic - {} clients".format(self.bands[0]), _graph_title="Individual download throughput for VO(WIFI) traffic - {} clients".format(
key),
_title_size=16, _title_size=16,
_bar_width=0.15, _color_name=['blueviolet'], _bar_width=0.15, _color_name=['blueviolet'],
_graph_image_name="{}_voice_{}".format(self.bands[0], count), _enable_csv=True,
_graph_image_name="{}_voice_{}".format(key, load),
_color_edge=['black'], _color_edge=['black'],
_color=['blueviolet']) _color=['blueviolet'])
graph_png = graph.build_bar_graph() graph_png = graph.build_bar_graph()
@@ -654,38 +619,12 @@ class ThroughputQOS(Realm):
report.set_graph_image(graph_png) report.set_graph_image(graph_png)
# need to move the graph image to the results # need to move the graph image to the results
report.move_graph_image() report.move_graph_image()
report.set_csv_filename(graph_png)
report.move_csv_file()
report.build_graph() report.build_graph()
count += 1
else: else:
print("No individual graph to generate.") print("No individual graph to generate.")
def test_setup_information(self, test_setup_data=None, colmn="Setup Information"):
# custom table for test-setup/input-setup information
if test_setup_data is None:
return None
else:
var = ""
for i in test_setup_data:
var = var + "<tr><td>" + i + "</td><td colspan='3'>" + str(test_setup_data[i]) + "</td></tr>"
setup_information = """
<!-- Test Setup Information -->
<br><br>
<table width='700px' border='1' cellpadding='2' cellspacing='0' style='border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px'>
<tr>
<th colspan='2'> Test Setup Information </th>
</tr>
<tr>
<td>""" + colmn + """</td>
<td>
<table width='100%' border='0' cellpadding='2' cellspacing='0' style='border-top-color: gray; border-top-style: solid; border-top-width: 1px; border-right-color: gray; border-right-style: solid; border-right-width: 1px; border-bottom-color: gray; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: gray; border-left-style: solid; border-left-width: 1px'>
""" + str(var) + """
</table>
</td>
</tr>
</table>
<br><br>
"""
return str(setup_information)
def main(): def main():
@@ -702,7 +641,7 @@ Generic command layout:
python3 ./throughput_QOS.py python3 ./throughput_QOS.py
--upstream_port eth1 --upstream_port eth1
--radio wiphy0 --radio_2g wiphy0
--num_stations 32 --num_stations 32
--security {open|wep|wpa|wpa2|wpa3} --security {open|wep|wpa|wpa2|wpa3}
--mode 1 --mode 1
@@ -722,8 +661,6 @@ python3 ./throughput_QOS.py
"bgnAX" : "13"} "bgnAX" : "13"}
--ssid netgear --ssid netgear
--password admin123 --password admin123
--test_duration 2m (default)
--monitor_interval_ms
--a_min 3000 --a_min 3000
--b_min 1000 --b_min 1000
--ap "00:0e:8e:78:e1:76" --ap "00:0e:8e:78:e1:76"
@@ -733,9 +670,8 @@ python3 ./throughput_QOS.py
--traffic_type lf_udp (traffic type, lf_udp | lf_tcp) --traffic_type lf_udp (traffic type, lf_udp | lf_tcp)
--test_duration 5m (duration to run traffic 5m --> 5 Minutes) --test_duration 5m (duration to run traffic 5m --> 5 Minutes)
--create_sta False (False, means it will not create stations and use the sta_names specified below) --create_sta False (False, means it will not create stations and use the sta_names specified below)
--sta_names sta000,sta001,sta002 (used if --create_sta False, comma separated names of stations) --sta_names sta000,sta001,sta002 (used if --create_sta is False, comma separated names of stations)
''') ''')
parser.add_argument('--mode', help='Used to force mode of stations', default="0") parser.add_argument('--mode', help='Used to force mode of stations', default="0")
parser.add_argument('--ap', help='Used to force a connection to a particular AP') parser.add_argument('--ap', help='Used to force a connection to a particular AP')
parser.add_argument('--traffic_type', help='Select the Traffic Type [lf_udp, lf_tcp]', required=True) parser.add_argument('--traffic_type', help='Select the Traffic Type [lf_udp, lf_tcp]', required=True)
@@ -748,22 +684,23 @@ python3 ./throughput_QOS.py
default="Best Effort") default="Best Effort")
parser.add_argument('--ap_name', help="AP Model Name", default="Test-AP") parser.add_argument('--ap_name', help="AP Model Name", default="Test-AP")
parser.add_argument('--bands', help='used to run on multiple radio bands,can be used with multiple stations', parser.add_argument('--bands', help='used to run on multiple radio bands,can be used with multiple stations',
default="2,4G, 5G, BOTH", required=True) default="2.4G, 5G, BOTH", required=True)
parser.add_argument('--ssid_2g', help="ssid for 2.4Ghz band") parser.add_argument('--ssid_2g', help="ssid for 2.4Ghz band")
parser.add_argument('--security_2g', help="security type for 2.4Ghz band") parser.add_argument('--security_2g', help="security type for 2.4Ghz band")
parser.add_argument('--passwd_2g', help="password for 2.4Ghz band") parser.add_argument('--passwd_2g', help="password for 2.4Ghz band")
parser.add_argument('--ssid_5g', help="ssid for 5Ghz band") parser.add_argument('--ssid_5g', help="ssid for 5Ghz band")
parser.add_argument('--security_5g', help="security type for 5Ghz band") parser.add_argument('--security_5g', help="security type for 5Ghz band")
parser.add_argument('--passwd_5g', help="password for 5Ghz band") parser.add_argument('--passwd_5g', help="password for 5Ghz band")
parser.add_argument('--radio_2g', help="radio which supports 2.4G bandwidth", default="wiphy0")
parser.add_argument('--radio_5g', help="radio which supports 5G bandwidth", default="wiphy1")
args = parser.parse_args() args = parser.parse_args()
print("--------------------------------------------") print("--------------------------------------------")
print(args) print(args)
print("--------------------------------------------") print("--------------------------------------------")
args.test_case = {} args.test_case = args.bands.split(',')
test_results = [] test_results = []
loads = {} loads = {}
bands = [] bands = []
radios = []
station_list = [] station_list = []
if (args.a_min is not None) and (args.b_min is not None): if (args.a_min is not None) and (args.b_min is not None):
@@ -779,11 +716,6 @@ python3 ./throughput_QOS.py
if args.bands is not None: if args.bands is not None:
bands = args.bands.split(',') bands = args.bands.split(',')
if args.radio is not None:
radios = args.radio.split(',')
if len(radios) < 2:
radios.extend(radios[0])
if args.test_duration is not None: if args.test_duration is not None:
args.test_duration = args.test_duration.strip('m') args.test_duration = args.test_duration.strip('m')
@@ -793,59 +725,44 @@ python3 ./throughput_QOS.py
for i in range(len(bands)): for i in range(len(bands)):
if bands[i] == "2.4G" or bands[i] == "2.4g": if bands[i] == "2.4G" or bands[i] == "2.4g":
args.bands = bands[i] args.bands = bands[i]
if args.mode is not None:
args.mode = 11 args.mode = 11
if i == 0:
args.radio = radios[0]
args.test_case.update({bands[i]: radios[0]})
else:
args.radio = radios[1]
args.test_case.update({bands[i]: radios[1]})
if args.create_sta: if args.create_sta:
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=int(args.num_stations) - 1, station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=int(args.num_stations) - 1,
padding_number_=10000, radio=args.radio) padding_number_=10000, radio=args.radio_2g)
else: else:
station_list = args.sta_names.split(",") station_list = args.sta_names.split(",")
elif bands[i] == "5G" or bands[i] == "5g": elif bands[i] == "5G" or bands[i] == "5g":
args.bands = bands[i] args.bands = bands[i]
args.mode = 9 args.mode = 9
if i == 0:
args.radio = radios[0]
args.test_case.update({bands[i]: radios[0]})
else:
args.radio = radios[1]
args.test_case.update({bands[i]: radios[1]})
if args.create_sta: if args.create_sta:
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=int(args.num_stations) - 1, station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=int(args.num_stations) - 1,
padding_number_=10000, padding_number_=10000,
radio=args.radio) radio=args.radio_5g)
else: else:
station_list = args.sta_names.split(",") station_list = args.sta_names.split(",")
elif bands[i] == "BOTH" or bands[i] == "both": elif bands[i] == "BOTH" or bands[i] == "both":
args.bands = bands[i] args.bands = bands[i]
args.radio = str(radios[0] + "," + radios[1]) args.mode = 0
args.test_case.update({bands[i]: radios[0] + "," + radios[1]}) if (int(args.num_stations) % 2) != 0:
print("Number of stations for Both Band should be even in number.")
exit(1)
mid = int(args.num_stations) // 2 mid = int(args.num_stations) // 2
if args.create_sta: if args.create_sta:
station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=mid - 1, station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=mid - 1,
padding_number_=10000, padding_number_=10000,
radio=radios[0]) radio=args.radio_2g)
station_list.extend(LFUtils.portNameSeries(prefix_="sta", start_id_=mid, station_list.extend(LFUtils.portNameSeries(prefix_="sta", start_id_=mid,
end_id_=int(args.num_stations) - 1, end_id_=int(args.num_stations) - 1,
padding_number_=10000, padding_number_=10000,
radio=radios[1])) radio=args.radio_5g))
else: else:
station_list = args.sta_names.split(",") station_list = args.sta_names.split(",")
else: else:
print("Band " + bands[i] + " Not Exist") print("Band " + bands[i] + " Not Exist")
exit(1) exit(1)
print("-----------------") print("------------------------")
# print(bands[i]) print(args.bands)
print(args.radio) print("------------------------")
# print(args.mode)
# print(station_list)
print(args.test_case)
print("-----------------")
# ---------------------------------------# # ---------------------------------------#
for index in range(len(loads["b_min"])): for index in range(len(loads["b_min"])):
throughput_qos = ThroughputQOS(host=args.mgr, throughput_qos = ThroughputQOS(host=args.mgr,
@@ -865,11 +782,12 @@ python3 ./throughput_QOS.py
ssid_5g=args.ssid_5g, ssid_5g=args.ssid_5g,
password_5g=args.passwd_5g, password_5g=args.passwd_5g,
security_5g=args.security_5g, security_5g=args.security_5g,
radio=args.radio, radio_2g=args.radio_2g,
radio_5g=args.radio_5g,
test_duration=args.test_duration, test_duration=args.test_duration,
use_ht160=False, use_ht160=False,
side_a_min_rate=loads['a_min'][index], side_a_min_rate=int(loads['a_min'][index]),
side_b_min_rate=loads['b_min'][index], side_b_min_rate=int(loads['b_min'][index]),
mode=args.mode, mode=args.mode,
bands=args.bands, bands=args.bands,
ap=args.ap, ap=args.ap,
@@ -888,11 +806,10 @@ python3 ./throughput_QOS.py
layer3connections = ','.join([[*x.keys()][0] for x in throughput_qos.json_get('endp')['endpoint']]) layer3connections = ','.join([[*x.keys()][0] for x in throughput_qos.json_get('endp')['endpoint']])
except: except:
raise ValueError('Try setting the upstream port flag if your device does not have an eth1 port') raise ValueError('Try setting the upstream port flag if your device does not have an eth1 port')
throughput_qos.start(False, False) throughput_qos.start(False, False)
time.sleep(int(args.test_duration) * 60) time.sleep(int(args.test_duration) * 60)
throughput_qos.stop() throughput_qos.stop()
test_results.append(throughput_qos.evaluate_throughput()) test_results.append(throughput_qos.evaluate_qos())
if args.create_sta: if args.create_sta:
if not throughput_qos.passes(): if not throughput_qos.passes():
print(throughput_qos.get_fail_message()) print(throughput_qos.get_fail_message())
@@ -909,7 +826,8 @@ python3 ./throughput_QOS.py
"SSID": throughput_qos.ssid, "SSID": throughput_qos.ssid,
"SSID - 2.4 Ghz": throughput_qos.ssid_2g, "SSID - 2.4 Ghz": throughput_qos.ssid_2g,
"SSID - 5 Ghz": throughput_qos.ssid_5g, "SSID - 5 Ghz": throughput_qos.ssid_5g,
"Test Duration": datetime.datetime.strptime(test_end_time, "%b %d %H:%M:%S") - datetime.datetime.strptime(test_start_time, "%b %d %H:%M:%S") "Test Duration": datetime.datetime.strptime(test_end_time, "%b %d %H:%M:%S") - datetime.datetime.strptime(
test_start_time, "%b %d %H:%M:%S")
} }
if throughput_qos.ssid is None: if throughput_qos.ssid is None:
test_setup_info.pop("SSID") test_setup_info.pop("SSID")