1#!/usr/bin/env python3 2# 3# Copyright 2018 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the 'License'); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an 'AS IS' BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16import json 17import os 18 19import acts_contrib.test_utils.power.PowerBaseTest as PBT 20import acts_contrib.test_utils.cellular.cellular_base_test as CBT 21from acts_contrib.test_utils.power import plot_utils 22from acts import context 23 24 25class PowerCellularLabBaseTest(CBT.CellularBaseTest, PBT.PowerBaseTest): 26 """ Base class for Cellular power related tests. 27 28 Inherits from both PowerBaseTest and CellularBaseTest so it has methods to 29 collect power measurements and run a cellular simulation. 30 """ 31 def __init__(self, controllers): 32 """ Class initialization. 33 34 Sets class attributes to None. 35 """ 36 37 super().__init__(controllers) 38 self.power_results = {} 39 40 def setup_test(self): 41 """ Turn screen on before starting a test. """ 42 43 super().setup_test() 44 try: 45 # Save a json file for device info 46 path = os.path.join(self.log_path, 'device_info.json') 47 48 self.log.info('save the device info to {}'.format(path)) 49 baseband = self.dut.adb.getprop('gsm.version.baseband') 50 self.dut.add_device_info('baseband', baseband) 51 with open(path, 'w') as f: 52 json.dump( 53 self.dut.device_info, 54 f, 55 indent=2, 56 sort_keys=True) 57 except Exception as e: 58 self.log.error('error in saving device_info: {}'.format(e)) 59 60 # Make the device go to sleep 61 self.dut.droid.goToSleepNow() 62 63 return True 64 65 def collect_power_data(self): 66 """ Collect power data using base class method and plot result 67 histogram. """ 68 69 samples = super().collect_power_data() 70 plot_title = '{}_{}_{}_histogram'.format( 71 self.test_name, self.dut.model, self.dut.build_info['build_id']) 72 plot_utils.monsoon_histogram_plot(samples, self.mon_info.data_path, 73 plot_title) 74 return samples 75 76 def teardown_test(self): 77 """ Executed after every test case, even if it failed or an exception 78 happened. 79 80 Save results to dictionary so they can be displayed after completing 81 the test batch. 82 """ 83 super().teardown_test() 84 85 self.power_results[self.test_name] = self.power_result.metric_value 86 87 def teardown_class(self): 88 """Clean up the test class after tests finish running. 89 90 Stops the simulation and disconnects from the Anritsu Callbox. Then 91 displays the test results. 92 93 """ 94 super().teardown_class() 95 96 # Log a summary of results 97 results_table_log = 'Results for cellular power tests:' 98 99 for test_name, value in self.power_results.items(): 100 results_table_log += '\n{}\t{}'.format(test_name, value) 101 102 # Save this summary to a csv file in the logs directory 103 self.save_summary_to_file() 104 105 self.log.info(results_table_log) 106 107 def save_summary_to_file(self): 108 """ Creates CSV format files with a summary of results. 109 110 This CSV files can be easily imported in a spreadsheet to analyze the 111 results obtained from the tests. 112 """ 113 114 # Save a csv file with the power measurements done in all the tests 115 116 path = os.path.join(self.log_path, self.RESULTS_SUMMARY_FILENAME) 117 118 # To avoid the test overwrite each other, open file with 'a' option 119 csvfile_exist = os.path.exists(path) 120 121 with open(path, 'a') as csvfile: 122 if not csvfile_exist: 123 csvfile.write('test,avg_power') 124 for test_name, value in self.power_results.items(): 125 csvfile.write('\n{},{}'.format(test_name, value)) 126 127 # Save a csv file with the calibration table for each simulation type 128 129 for sim_type in self.calibration_table: 130 131 path = os.path.join( 132 self.log_path, '{}_{}'.format(sim_type, 133 self.CALIBRATION_TABLE_FILENAME)) 134 135 with open(path, 'w') as csvfile: 136 csvfile.write('band,dl_pathloss, ul_pathloss') 137 for band, pathloss in self.calibration_table[sim_type].items(): 138 csvfile.write('\n{},{},{}'.format( 139 band, pathloss.get('dl', 'Error'), 140 pathloss.get('ul', 'Error'))) 141