1# Copyright 2022 - The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the 'License'); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an 'AS IS' BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14import os 15import time 16 17import acts_contrib.test_utils.power.cellular.cellular_power_preset_base_test as PB 18 19 20class PowerTelTrafficPresetTest(PB.PowerCellularPresetLabBaseTest): 21 # command to enable mobile data 22 ADB_CMD_ENABLE_MOBILE_DATA = 'svc data enable' 23 24 # command to start iperf server on UE 25 START_IPERF_SV_UE_CMD = 'nohup > /dev/null 2>&1 sh -c "iperf3 -s -i1 -p5201 > /dev/null &"' 26 27 # command to start iperf server on UE 28 # (require: 1.path to iperf exe 2.hostname/hostIP) 29 START_IPERF_CLIENT_UE_CMD = 'nohup > /dev/null 2>&1 sh -c "iperf3 -c {iperf_host_ip} -i1 -p5202 -w8m -t2000 > /dev/null &"' 30 31 # command to start iperf server on host() 32 START_IPERF_SV_HOST_CMD = '{exe_path}\\iperf3 -s -p5202' 33 34 # command to start iperf client on host 35 # (require: 1.path to iperf exe 2.UE IP) 36 START_IPERF_CLIENT_HOST_CMD = ( 37 '{exe_path}\\iperf3 -c {ue_ip} -w16M -t1000 -p5201') 38 39 START_IPERF_CLIENT_HOST_CMD_FR2 = ( 40 '{exe_path}\\iperf3 -c {ue_ip} -w16M -t1000 -p5201 -P32') 41 42 def __init__(self, controllers): 43 super().__init__(controllers) 44 self.ssh_iperf_client = None 45 self.ssh_iperf_server = None 46 self.iperf_out_err = {} 47 48 def setup_class(self): 49 super().setup_class() 50 51 # Unpack test parameters used in this class 52 self.unpack_userparams(iperf_exe_path=None, 53 ue_ip=None, 54 iperf_host_ip=None) 55 56 # Verify required config 57 for param in ('iperf_exe_path', 'ue_ip', 'iperf_host_ip'): 58 if getattr(self, param) is None: 59 raise RuntimeError( 60 f'Parameter "{param}" is required to run this type of test') 61 62 def setup_test(self): 63 # Call parent method first to setup simulation 64 super().setup_test() 65 66 # setup ssh client 67 self.ssh_iperf_client = self.cellular_simulator.create_ssh_client() 68 self.ssh_iperf_server = self.cellular_simulator.create_ssh_client() 69 70 self.turn_on_mobile_data() 71 72 def power_tel_traffic_test(self): 73 """Measure power while data is transferring.""" 74 # Start data traffic 75 self.start_uplink_process() 76 time.sleep(5) 77 self.start_downlink_process() 78 79 # Measure power 80 self.collect_power_data() 81 82 # Write iperf log 83 self.ssh_iperf_server.close() 84 uplink_log_name = self.test_name + '_uplink.txt' 85 self._write_iperf_log(uplink_log_name, self.ssh_iperf_server) 86 self.ssh_iperf_client.close() 87 downlink_log_name = self.test_name + '_downlink.txt' 88 self._write_iperf_log(downlink_log_name, self.ssh_iperf_client) 89 90 def _exec_ssh_cmd(self, ssh_client, cmd): 91 """Execute command on given ssh client. 92 93 Args: 94 ssh_client: parmiko ssh client object. 95 cmd: command to execute via ssh. 96 """ 97 self.log.info('Sending cmd to ssh host: ' + cmd) 98 stdin, stdout, stderr = ssh_client.exec_command(cmd, get_pty=True) 99 stdin.close() 100 self.iperf_out_err[ssh_client] = (stdout, stderr) 101 102 def start_downlink_process(self): 103 """UE transfer data to host.""" 104 self.log.info('Start downlink process') 105 # start UE iperf server 106 self.cellular_dut.ad.adb.shell(self.START_IPERF_SV_UE_CMD) 107 self.log.info('cmd sent to UE: ' + self.START_IPERF_SV_UE_CMD) 108 self.log.info('UE iperf server started') 109 time.sleep(5) 110 # start host iperf client 111 cmd = None 112 if 'fr2' in self.test_name: 113 cmd = self.START_IPERF_CLIENT_HOST_CMD_FR2.format( 114 exe_path=self.iperf_exe_path, 115 ue_ip=self.ue_ip) 116 else: 117 cmd = self.START_IPERF_CLIENT_HOST_CMD.format( 118 exe_path=self.iperf_exe_path, 119 ue_ip=self.ue_ip) 120 121 if not cmd: 122 raise RuntimeError('Cannot format command to start iperf client.') 123 self._exec_ssh_cmd(self.ssh_iperf_client, cmd) 124 self.log.info('Host iperf client started') 125 time.sleep(5) 126 127 def start_uplink_process(self): 128 """Host transfer data to UE.""" 129 self.log.info('Start uplink process') 130 # start host iperf server 131 cmd = self.START_IPERF_SV_HOST_CMD.format(exe_path=self.iperf_exe_path) 132 self._exec_ssh_cmd(self.ssh_iperf_server, cmd) 133 self.log.info('Host iperf server started') 134 time.sleep(5) 135 # start UE iperf 136 adb_cmd = self.START_IPERF_CLIENT_UE_CMD.format( 137 iperf_host_ip=self.iperf_host_ip) 138 self.cellular_dut.ad.adb.shell(adb_cmd) 139 self.log.info('cmd sent to UE: ' + adb_cmd) 140 self.log.info('UE iperf client started') 141 time.sleep(5) 142 143 def _write_iperf_log(self, file_name, ssh): 144 """ Writing ssh stdout and stdin to log file. 145 146 Args: 147 file_name: log file name to write log to. 148 ssh: paramiko client object. 149 """ 150 iperf_log_dir = os.path.join(self.root_output_path, 'iperf') 151 os.makedirs(iperf_log_dir, exist_ok=True) 152 iperf_log_file_path = os.path.join(iperf_log_dir, file_name) 153 with open(iperf_log_file_path, 'w') as f: 154 out, err = self.iperf_out_err[ssh] 155 out_content = ''.join(out.readlines()) 156 err_content = ''.join(err.readlines()) 157 f.write(out_content) 158 f.write('\nErrors:\n') 159 f.write(err_content) 160 161 def turn_on_mobile_data(self): 162 self.dut.adb.shell(self.ADB_CMD_ENABLE_MOBILE_DATA) 163 164 165class PowerTelTraffic_Preset_Test(PowerTelTrafficPresetTest): 166 def test_preset_LTE_traffic(self): 167 self.power_tel_traffic_test() 168 169 def test_preset_nsa_traffic_fr1(self): 170 self.power_tel_traffic_test() 171 172 def test_preset_sa_traffic_fr1(self): 173 self.power_tel_traffic_test() 174 175 176class PowerTelTrafficFr2_Preset_Test(PowerTelTrafficPresetTest): 177 def test_preset_nsa_traffic_fr2(self): 178 self.power_tel_traffic_test() 179