bugfix: Harmonize test/trial RFC2544 terminology
[vswitchperf.git] / core / traffic_controller_rfc2544.py
1 # Copyright 2015 Intel Corporation.
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.
14 """RFC2544 Traffic Controller implementation.
15 """
16 import logging
17
18 from core.traffic_controller import ITrafficController
19 from core.results.results_constants import ResultsConstants
20 from core.results.results import IResults
21 from conf import settings
22 from conf import get_test_param
23
24
25 class TrafficControllerRFC2544(ITrafficController, IResults):
26     """Traffic controller for RFC2544 traffic
27
28     Used to setup and control a traffic generator for an RFC2544 deployment
29     traffic scenario.
30     """
31
32     def __init__(self, traffic_gen_class):
33         """Initialise the trafficgen and store.
34
35         :param traffic_gen_class: The traffic generator class to be used.
36         """
37         self._logger = logging.getLogger(__name__)
38         self._logger.debug("__init__")
39         self._traffic_gen_class = traffic_gen_class()
40         self._traffic_started = False
41         self._traffic_started_call_count = 0
42         self._tests = int(get_test_param('rfc2544_tests', 1))
43         self._duration = int(get_test_param('duration', 30))
44         self._lossrate = float(get_test_param('lossrate', 0.0))
45         self._results = []
46
47         # If set, comma separated packet_sizes value from --test_params
48         # on cli takes precedence over value in settings file.
49         self._packet_sizes = None
50         packet_sizes_cli = get_test_param('pkt_sizes')
51         if packet_sizes_cli:
52             self._packet_sizes = [int(x.strip())
53                                   for x in packet_sizes_cli.split(',')]
54         else:
55             self._packet_sizes = settings.getValue('TRAFFICGEN_PKT_SIZES')
56
57     def __enter__(self):
58         """Call initialisation function.
59         """
60         self._traffic_gen_class.connect()
61
62     def __exit__(self, type_, value, traceback):
63         """Stop traffic, clean up.
64         """
65         if self._traffic_started:
66             self.stop_traffic()
67
68     @staticmethod
69     def _append_results(result_dict, packet_size):
70         """Adds common values to traffic generator results.
71
72         :param result_dict: Dictionary containing results from trafficgen
73         :param packet_size: Packet size value.
74
75         :returns: dictionary of results with additional entries.
76         """
77
78         ret_value = result_dict
79
80         # TODO Old TOIT controller had knowledge about scenario beeing
81         # executed, should new controller also fill Configuration & ID,
82         # or this should be passed to TestCase?
83         ret_value[ResultsConstants.TYPE] = 'rfc2544'
84         ret_value[ResultsConstants.PACKET_SIZE] = str(packet_size)
85
86         return ret_value
87
88     def send_traffic(self, traffic):
89         """See ITrafficController for description
90         """
91         self._logger.debug('send_traffic with ' +
92                            str(self._traffic_gen_class))
93
94         for packet_size in self._packet_sizes:
95             # Merge framesize with the default traffic definition
96             if 'l2' in traffic:
97                 traffic['l2'] = dict(traffic['l2'],
98                                      **{'framesize': packet_size})
99             else:
100                 traffic['l2'] = {'framesize': packet_size}
101
102             if traffic['traffic_type'] == 'back2back':
103                 result = self._traffic_gen_class.send_rfc2544_back2back(
104                     traffic, tests=self._tests, duration=self._duration, lossrate=self._lossrate)
105             elif traffic['traffic_type'] == 'continuous':
106                 result = self._traffic_gen_class.send_cont_traffic(
107                     traffic, duration=self._duration)
108             else:
109                 result = self._traffic_gen_class.send_rfc2544_throughput(
110                     traffic, tests=self._tests, duration=self._duration, lossrate=self._lossrate)
111
112             result = TrafficControllerRFC2544._append_results(result,
113                                                               packet_size)
114             self._results.append(result)
115
116     def send_traffic_async(self, traffic, function):
117         """See ITrafficController for description
118         """
119         self._logger.debug('send_traffic_async with ' +
120                            str(self._traffic_gen_class))
121
122         for packet_size in self._packet_sizes:
123             traffic['l2'] = {'framesize': packet_size}
124             self._traffic_gen_class.start_rfc2544_throughput(
125                 traffic,
126                 tests=self._tests,
127                 duration=self._duration)
128             self._traffic_started = True
129             if len(function['args']) > 0:
130                 function['function'](function['args'])
131             else:
132                 function['function']()
133             result = self._traffic_gen_class.wait_rfc2544_throughput()
134             result = TrafficControllerRFC2544._append_results(result,
135                                                               packet_size)
136             self._results.append(result)
137
138     def stop_traffic(self):
139         """Kills traffic being sent from the traffic generator.
140         """
141         self._logger.debug("stop_traffic()")
142
143     def print_results(self):
144         """IResult interface implementation.
145         """
146         counter = 0
147         for item in self._results:
148             logging.info("Record: " + str(counter))
149             counter += 1
150             for(key, value) in list(item.items()):
151                 logging.info("         Key: " + str(key) +
152                              ", Value: " + str(value))
153
154     def get_results(self):
155         """IResult interface implementation.
156         """
157         return self._results
158
159     def validate_send_traffic(self, dummy_result, dummy_traffic):
160         """Verify that send traffic has succeeded
161         """
162         if len(self._results):
163             if 'b2b_frames' in self._results[-1]:
164                 return float(self._results[-1]['b2b_frames']) > 0
165             elif 'throughput_rx_fps' in self._results[-1]:
166                 return float(self._results[-1]['throughput_rx_fps']) > 0
167             else:
168                 return True
169         else:
170             return False