blob: 4d8dc56adaaf759ea6bf1949e55871f854b7484b [file] [log] [blame]
# Copyright (C) 2024 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.
"""iperf test util."""
import time
from mobly import utils
from mobly.controllers import android_device
# IPv4, 10 sec, 1 stream
DEFAULT_IPV4_CLIENT_ARGS = '-t 10 -P1'
DEFAULT_IPV4_SERVER_ARGS = '-J'
GROUP_OWNER_IPV4_ADDR_LEN_MAX = 15
IPERF_SERVER_START_DELAY_SEC = 1
IPERF_DEBUG_TIME_SEC = 300
class IPerfServerOnDevice:
"""Class that handles iperf3 server operations on device."""
def __init__(self, serial, arg=DEFAULT_IPV4_SERVER_ARGS):
self.iperf_str = 'adb -s {serial} shell iperf3 -s {arg}'.format(
serial=serial, arg=arg
)
self.iperf_process = None
self.started = False
def start(self):
"""Starts iperf server on specified port."""
if self.started:
return
cmd = self.iperf_str
self.iperf_process = utils.start_standing_subprocess(cmd, shell=True)
self.started = True
def stop(self):
if self.started:
utils.stop_standing_subprocess(self.iperf_process)
self.started = False
def run_iperf_test(
ad_network_client: android_device.AndroidDevice,
ad_network_owner: android_device.AndroidDevice,
) -> int:
"""Run iperf test from ad_network_client to ad_network_owner.
Args:
ad_network_client: android device that is the client in the iperf test.
ad_network_owner: android device that is the server in the iperf test.
Returns:
speed in KB/s if there is a valid result or -1.
"""
speed_kbyte_sec = -1
group_owner_addr = get_group_owner_addr(ad_network_client)
if not group_owner_addr:
return speed_kbyte_sec
client_arg = DEFAULT_IPV4_CLIENT_ARGS
server_arg = DEFAULT_IPV4_SERVER_ARGS
# Check if group owner address is an IPv6 address
if len(group_owner_addr) > GROUP_OWNER_IPV4_ADDR_LEN_MAX:
client_arg = DEFAULT_IPV4_CLIENT_ARGS + ' -6'
server_arg = DEFAULT_IPV4_SERVER_ARGS + ' -6'
server = IPerfServerOnDevice(ad_network_owner.serial, server_arg)
try:
ad_network_owner.log.info('Start iperf server')
server.start()
time.sleep(IPERF_SERVER_START_DELAY_SEC)
ad_network_client.log.info('Start iperf client')
success, result_list = ad_network_client.run_iperf_client(
group_owner_addr, client_arg
)
result = ''.join(result_list)
last_mbits_sec_index = result.rfind('Mbits/sec')
if success and last_mbits_sec_index > 0:
speed_mbps = int(
float(result[:last_mbits_sec_index].strip().split(' ')[-1])
)
speed_kbyte_sec = int(speed_mbps * 1024 / 8)
else:
ad_network_client.log.info('Can not find valid iperf test result')
except android_device.adb.AdbError:
ad_network_client.log.info('run_iperf_client() failed')
owner_ifconfig = get_ifconfig(ad_network_owner)
client_ifconfig = get_ifconfig(ad_network_client)
ad_network_client.log.info(client_ifconfig)
ad_network_client.log.info(group_owner_addr)
ad_network_client.log.info(client_arg)
ad_network_owner.log.info(owner_ifconfig)
# time.sleep(IPERF_DEBUG_TIME_SEC)
else:
server.stop()
return speed_kbyte_sec
def get_ifconfig(
ad: android_device.AndroidDevice,
) -> str:
"""Get network info from adb shell ifconfig."""
return ad.adb.shell('ifconfig').decode('utf-8').strip()
def get_group_owner_addr(
ad: android_device.AndroidDevice,
) -> str:
"""Get WFD group owner address from adb shell dumpsys wifip2p."""
try:
return (
ad.adb.shell(
'dumpsys wifip2p | egrep "groupOwnerAddress|groupOwnerIpAddress"'
)
.decode('utf-8')
.strip()
.split()[-1]
.replace('/', '')
)
except android_device.adb.Error:
ad.log.info('Failed to get group owner address.')
return ''