blob: d95183a403732e709bcb0edfcc964aabe4a1d8eb [file] [log] [blame]
#!/usr/bin/env python3.4
#
# Copyright 2018 - The Android Open Source Project
#
# 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
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import statistics
import acts.controllers.iperf_server as ipf
class IperfHelper(object):
""" Helps with iperf config and processing the results
This class can be used to process the results of multiple iperf servers
(for example, dual traffic scenarios). It also helps in setting the
correct arguments for when using the phone as an iperf server
"""
IPERF_CLIENT_RESULT_FILE_LOC_PHONE = '/sdcard/Download/'
def __init__(self, config):
self.traffic_type = config['traffic_type']
self.traffic_direction = config['traffic_direction']
self.duration = config['duration']
self.port = config['port']
self.server_idx = config['server_idx']
self.use_client_output = False
if 'bandwidth' in config:
self.bandwidth = config['bandwidth']
else:
self.bandwidth = None
if 'start_meas_time' in config:
self.start_meas_time = config['start_meas_time']
else:
self.start_meas_time = 0
self.window = getattr(config, "window", None)
iperf_args = '-i 1 -t {} -p {} -J'.format(self.duration, self.port)
if self.traffic_type == "UDP":
iperf_args = iperf_args + ' -u'
if self.traffic_direction == "DL":
iperf_args = iperf_args + ' -R'
self.use_client_output = True
# Set bandwidth in Mbit/s
if self.bandwidth is not None:
iperf_args = iperf_args + ' -b {}M'.format(self.bandwidth)
# Set the TCP window size
if self.window:
iperf_args += ' -w {}M'.format(self.window)
# Parse the client side data to a file saved on the phone
self.results_filename_phone = self.IPERF_CLIENT_RESULT_FILE_LOC_PHONE \
+ 'iperf_client_port_{}_{}.log'.format( \
self.port, self.traffic_direction)
iperf_args = iperf_args + ' > %s' % self.results_filename_phone
self.iperf_args = iperf_args
def process_iperf_results(self, dut, log, iperf_servers, test_name):
"""Gets the iperf results from the phone and computes the average rate
Returns:
throughput: the average throughput (Mbit/s).
"""
# Get IPERF results and add this to the plot title
RESULTS_DESTINATION = os.path.join(
iperf_servers[self.server_idx].log_path,
'iperf_client_output_{}.log'.format(test_name))
PULL_FILE = '{} {}'.format(self.results_filename_phone,
RESULTS_DESTINATION)
dut.adb.pull(PULL_FILE)
# Calculate the average throughput
if self.use_client_output:
iperf_file = RESULTS_DESTINATION
else:
iperf_file = iperf_servers[self.server_idx].log_files[-1]
try:
iperf_result = ipf.IPerfResult(iperf_file)
# Get instantaneous rates after measuring starts
samples = iperf_result.instantaneous_rates[self.start_meas_time:-1]
# Convert values to Mbit/s
samples = [rate * 8 * (1.024**2) for rate in samples]
# compute mean, var and max_dev
mean = statistics.mean(samples)
var = statistics.variance(samples)
max_dev = 0
for rate in samples:
if abs(rate - mean) > max_dev:
max_dev = abs(rate - mean)
log.info('The average throughput is {}. Variance is {} and max '
'deviation is {}.'.format(
round(mean, 2), round(var, 2), round(max_dev, 2)))
except:
log.warning('Cannot get iperf result.')
mean = 0
return mean