4 ## Copyright (c) 2020 Intel Corporation
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
11 ## http://www.apache.org/licenses/LICENSE-2.0
13 ## Unless required by applicable law or agreed to in writing, software
14 ## distributed under the License is distributed on an "AS IS" BASIS,
15 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 ## See the License for the specific language governing permissions and
17 ## limitations under the License.
23 from rapid_log import RapidLog
24 from rapid_test import RapidTest
25 from statistics import mean
27 class ImpairTest(RapidTest):
29 Class to manage the impair testing
31 def __init__(self, test_param, lat_percentile, runtime, pushgateway,
32 environment_file, gen_machine, sut_machine):
33 super().__init__(test_param, runtime, pushgateway, environment_file)
34 self.gen_machine = gen_machine
35 self.sut_machine = sut_machine
36 self.test['lat_percentile'] = lat_percentile
39 # fieldnames = ['Flows','PacketSize','RequestedPPS','GeneratedPPS','SentPPS','ForwardedPPS','ReceivedPPS','AvgLatencyUSEC','MaxLatencyUSEC','Dropped','DropRate']
40 # writer = csv.DictWriter(data_csv_file, fieldnames=fieldnames)
41 # writer.writeheader()
42 imix = self.test['imix']
44 flow_number = self.test['flowsize']
46 self.gen_machine.set_udp_packet_size(imix)
47 flow_number = self.gen_machine.set_flows(flow_number)
48 self.gen_machine.start_latency_cores()
49 RapidLog.info("+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+")
50 RapidLog.info("| Generator is sending UDP ({:>5} flow) packets ({:>5} bytes) to SUT via GW dropping and delaying packets. SUT sends packets back. Use ctrl-c to stop the test |".format(flow_number,size))
51 RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
52 RapidLog.info('| Test | Speed requested | Gen by core | Sent by NIC | Fwrd by SUT | Rec. by core | Avg. Lat.|{:.0f} Pcentil| Max. Lat.| Sent | Received | Lost | Total Lost|L.Ratio|Time|'.format(self.test['lat_percentile']*100))
53 RapidLog.info("+--------+------------------+-------------+-------------+-------------+------------------------+----------+----------+----------+-----------+-----------+-----------+-----------+-------+----+")
55 speed = self.test['startspeed']
56 self.gen_machine.set_generator_speed(speed)
59 print('Measurement ongoing at speed: ' + str(round(speed,2)) + '% ',end='\r')
62 # Get statistics now that the generation is stable and NO ARP messages any more
63 pps_req_tx,pps_tx,pps_sut_tx,pps_rx,lat_avg, lat_perc, lat_perc_max, lat_max, abs_tx, abs_rx, abs_dropped, abs_tx_fail, drop_rate, lat_min, lat_used, r, actual_duration = self.run_iteration(float(self.test['runtime']),flow_number,size,speed)
64 # Drop rate is expressed in percentage. lat_used is a ratio (0 to 1). The sum of these 2 should be 100%.
65 # If the sum is lower than 95, it means that more than 5% of the latency measurements where dropped for accuracy reasons.
66 if (drop_rate + lat_used * 100) < 95:
67 lat_warning = bcolors.WARNING + ' Latency accuracy issue?: {:>3.0f}%'.format(lat_used*100) + bcolors.ENDC
70 RapidLog.info(self.report_result(attempts,size,speed,pps_req_tx,pps_tx,pps_sut_tx,pps_rx,lat_avg,lat_perc,lat_perc_max,lat_max,abs_tx,abs_rx,abs_dropped,actual_duration))
71 # writer.writerow({'Flows':flow_number,'PacketSize':(size+4),'RequestedPPS':self.get_pps(speed,size),'GeneratedPPS':pps_req_tx,'SentPPS':pps_tx,'ForwardedPPS':pps_sut_tx_str,'ReceivedPPS':pps_rx,'AvgLatencyUSEC':lat_avg,'MaxLatencyUSEC':lat_max,'Dropped':abs_dropped,'DropRate':drop_rate})
72 if self.test['pushgateway']:
73 URL = self.test['pushgateway'] + self.test['test'] + '/instance/' + self.test['environment_file']
74 DATA = 'Flows {}\nPacketSize {}\nRequestedPPS {}\nGeneratedPPS {}\nSentPPS {}\nForwardedPPS {}\nReceivedPPS {}\nAvgLatencyUSEC {}\nMaxLatencyUSEC {}\nDropped {}\nDropRate {}\n'.format(flow_number,size+4,self.get_pps(speed,size),pps_req_tx,pps_tx,pps_sut_tx,pps_rx,lat_avg,lat_max,abs_dropped,drop_rate)
75 HEADERS = {'X-Requested-With': 'Python requests', 'Content-type': 'text/xml'}
76 response = requests.post(url=URL, data=DATA,headers=HEADERS)
77 if (response.status_code != 202) and (response.status_code != 200):
78 RapidLog.info('Cannot send metrics to {}'.format(URL))
80 self.gen_machine.stop_latency_cores()