• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 2022 - 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.
16
17import collections
18import csv
19import itertools
20import numpy
21import json
22import re
23import os
24from acts import context
25from acts import base_test
26from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger
27from acts_contrib.test_utils.cellular.performance import cellular_performance_test_utils as cputils
28from acts_contrib.test_utils.cellular.performance.CellularThroughputBaseTest import CellularThroughputBaseTest
29from acts_contrib.test_utils.wifi import wifi_performance_test_utils as wputils
30from acts_contrib.test_utils.wifi.wifi_performance_test_utils.bokeh_figure import BokehFigure
31from functools import partial
32
33
34class CellularLteFr1EndcRvrTest(CellularThroughputBaseTest):
35    """Class to test ENDC sensitivity"""
36
37    def __init__(self, controllers):
38        base_test.BaseTestClass.__init__(self, controllers)
39        self.testcase_metric_logger = (
40            BlackboxMappedMetricLogger.for_test_case())
41        self.testclass_metric_logger = (
42            BlackboxMappedMetricLogger.for_test_class())
43        self.publish_testcase_metrics = True
44        self.testclass_params = self.user_params['endc_rvr_test_params']
45        self.tests = self.generate_test_cases(lte_dl_mcs_table='QAM256',
46                                              lte_ul_mcs_table='QAM256',
47                                              lte_ul_mcs=4,
48                                              nr_ul_mcs=4,
49                                              transform_precoding=0,
50                                              schedule_scenario='FULL_TPUT',
51                                              schedule_slot_ratio=80,
52                                              nr_dl_mcs_table='Q256',
53                                              nr_ul_mcs_table='Q64')
54
55    def process_testclass_results(self):
56        pass
57
58    def process_testcase_results(self):
59        if self.current_test_name not in self.testclass_results:
60            return
61        testcase_data = self.testclass_results[self.current_test_name]
62
63        average_power_list = []
64        cell_throughput_lists = {}
65        for current_cell_idx, current_cell in enumerate(testcase_data['testcase_params']['endc_combo_config']['cell_list']):
66            cell_throughput_lists[current_cell_idx]=[]
67
68        for result in testcase_data['results']:
69            for current_cell_idx, current_cell in enumerate(testcase_data['testcase_params']['endc_combo_config']['cell_list']):
70                if current_cell['cell_type'] == 'LTE':
71                    cell_throughput_lists[current_cell_idx].append(
72                        result['throughput_measurements']['lte_tput_result'][current_cell['cell_number']]
73                        ['DL']['average_tput'])
74                else:
75                    cell_throughput_lists[current_cell_idx].append(
76                        result['throughput_measurements']['nr_tput_result'][current_cell['cell_number']]
77                        ['DL']['average_tput'])
78            if self.power_monitor:
79                average_power_list.append(result['average_power'])
80
81        plot = BokehFigure(
82            title='ENDC RvR',
83            x_label='Cell Power (dBm/SCS)',
84            primary_y_label='PHY Rate (Mbps)',
85            secondary_y_label='Power Consumption (mW)')
86
87        for cell_idx, cell_throughput_list in cell_throughput_lists.items():
88            plot.add_line(
89                testcase_data['testcase_params']['cell_power_sweep'][cell_idx],
90                cell_throughput_lists[cell_idx],
91                'Cell {} - Average Throughput'.format(cell_idx),
92                width=1)
93
94        if self.power_monitor:
95            plot.add_line(
96                testcase_data['testcase_params']['cell_power_sweep'][0],
97                average_power_list,
98                'Power Consumption (mW)',
99                width=1,
100                style='dashdot',
101                y_axis='secondary')
102
103        plot.generate_figure()
104        output_file_path = os.path.join(self.log_path, '{}.html'.format(self.current_test_name))
105        BokehFigure.save_figure(plot, output_file_path)
106
107        results_file_path = os.path.join(
108            context.get_current_context().get_full_output_path(),
109            '{}.json'.format(self.current_test_name))
110        with open(results_file_path, 'w') as results_file:
111            json.dump(wputils.serialize_dict(testcase_data),
112                      results_file,
113                      indent=4)
114
115    def get_per_cell_power_sweeps(self, testcase_params):
116        cell_power_sweeps = []
117        # Construct test cell sweep
118        lte_sweep = list(
119            numpy.arange(self.testclass_params['lte_cell_power_start'],
120                         self.testclass_params['lte_cell_power_stop'],
121                         self.testclass_params['lte_cell_power_step']))
122        nr_sweep = list(
123            numpy.arange(self.testclass_params['nr_cell_power_start'],
124                         self.testclass_params['nr_cell_power_stop'],
125                         self.testclass_params['nr_cell_power_step']))
126        if len(lte_sweep) > len(nr_sweep):
127            nr_sweep_pad = len(lte_sweep) - len(nr_sweep)
128            nr_sweep.extend([nr_sweep[-1]]*nr_sweep_pad)
129        elif len(lte_sweep) < len(nr_sweep):
130            lte_sweep_pad = len(nr_sweep) - len(lte_sweep)
131            lte_sweep.extend([lte_sweep[-1]]*lte_sweep_pad)
132
133
134        for cell_idx, cell_config in enumerate(testcase_params['endc_combo_config']['cell_list']):
135            if testcase_params['test_cell_idx'] in [cell_idx, 'all']:
136                if cell_config['cell_type'] == 'LTE':
137                    cell_power_sweeps.append(lte_sweep)
138                elif cell_config['cell_type'] == 'NR5G':
139                    cell_power_sweeps.append(nr_sweep)
140            elif cell_config['cell_type'] == 'LTE':
141                cell_power_sweeps.append([self.testclass_params['lte_cell_power_start']
142                             ] * len(nr_sweep))
143            elif cell_config['cell_type'] == 'NR5G':
144                cell_power_sweeps.append([self.testclass_params['nr_cell_power_start']
145                             ] * len(lte_sweep))
146        return cell_power_sweeps
147
148    def generate_test_cases(self, lte_dl_mcs_table,
149                            lte_ul_mcs_table, lte_ul_mcs,
150                            nr_ul_mcs, **kwargs):
151        test_cases = []
152        with open(self.testclass_params['endc_combo_file'],
153                  'r') as endc_combos:
154            for endc_combo_str in endc_combos:
155                if endc_combo_str[0] == '#':
156                    continue
157                endc_combo_config = cputils.generate_endc_combo_config_from_string(
158                    endc_combo_str)
159                special_chars = '+[]=;,\n'
160                for char in special_chars:
161                    endc_combo_str = endc_combo_str.replace(char, '_')
162                endc_combo_str = endc_combo_str.replace('__', '_')
163                endc_combo_str = endc_combo_str.strip('_')
164                test_cell_list = list(range(len(endc_combo_config['cell_list'])))
165                test_cell_list.append('all')
166                for cell_idx in test_cell_list:
167                    test_name = 'test_rvr_{}_cell_{}'.format(
168                        endc_combo_str, cell_idx)
169                    test_params = collections.OrderedDict(
170                        endc_combo_config=endc_combo_config,
171                        test_cell_idx=cell_idx,
172                        lte_dl_mcs_table=lte_dl_mcs_table,
173                        lte_dl_mcs=self.testclass_params['link_adaptation_config']['LTE'],
174                        lte_ul_mcs_table=lte_ul_mcs_table,
175                        lte_ul_mcs=lte_ul_mcs,
176                        nr_dl_mcs=self.testclass_params['link_adaptation_config']['NR5G'],
177                        nr_ul_mcs=nr_ul_mcs,
178                        **kwargs)
179                    setattr(self, test_name,
180                            partial(self._test_throughput_bler, test_params))
181                    test_cases.append(test_name)
182        return test_cases