1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# Copyright 2015-2016 Intel Corporation.
#
# 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.
"""Base class for traffic controllers
"""
import logging
import os
import time
from core.results.results_constants import ResultsConstants
from conf import settings
class TrafficController(object):
"""Base class which defines a common functionality for all traffic
controller classes.
Used to setup and control a traffic generator for a particular deployment
scenario.
"""
def __init__(self, traffic_gen_class):
"""Initialization common for all types of traffic controllers
:param traffic_gen_class: The traffic generator class to be used.
"""
self._type = None
self._logger = logging.getLogger(__name__)
self._logger.debug("__init__")
self._traffic_gen_class = traffic_gen_class()
self._traffic_started = False
self._traffic_started_call_count = 0
self._duration = int(settings.getValue('TRAFFICGEN_DURATION'))
self._lossrate = float(settings.getValue('TRAFFICGEN_LOSSRATE'))
self._packet_sizes = settings.getValue('TRAFFICGEN_PKT_SIZES')
self._mode = settings.getValue('mode').lower()
self._results = []
def __enter__(self):
"""Call initialisation function.
"""
self._traffic_gen_class.connect()
def __exit__(self, type_, value, traceback):
"""Stop traffic, clean up.
"""
if self._traffic_started:
self.stop_traffic()
def _append_results(self, result_dict, packet_size):
"""Adds common values to traffic generator results.
:param result_dict: Dictionary containing results from trafficgen
:param packet_size: Packet size value.
:returns: dictionary of results with additional entries.
"""
ret_value = result_dict
ret_value[ResultsConstants.TYPE] = self._type
ret_value[ResultsConstants.PACKET_SIZE] = str(packet_size)
return ret_value
def traffic_required(self):
"""Checks selected '--mode' of traffic generator and performs
its specific handling.
:returns: True - in case that traffic generator should be executed
False - if traffic generation is not required
"""
if self._mode == 'trafficgen-off':
time.sleep(2)
self._logger.debug("All is set. Please run traffic generator manually.")
input(os.linesep + "Press Enter to terminate vswitchperf..." +
os.linesep + os.linesep)
return False
elif self._mode == 'trafficgen-pause':
time.sleep(2)
while True:
choice = input(os.linesep + 'Transmission paused, should'
' transmission be resumed? [y/n]' + os.linesep).lower()
if choice in ('yes', 'y', 'ye'):
return True
elif choice in ('no', 'n'):
self._logger.info("Traffic transmission will be skipped.")
return False
else:
print("Please respond with 'yes', 'y', 'no' or 'n' ", end='')
return True
def send_traffic(self, dummy_traffic):
"""Triggers traffic to be sent from the traffic generator.
This is a blocking function.
:param traffic: A dictionary describing the traffic to send.
"""
raise NotImplementedError(
"The TrafficController does not implement",
"the \"send_traffic\" function.")
def send_traffic_async(self, dummy_traffic, dummy_function):
"""Triggers traffic to be sent asynchronously.
This is not a blocking function.
:param traffic: A dictionary describing the traffic to send.
:param function: A dictionary describing the function to call between
send and wait in the form:
function = {
'function' : package.module.function,
'args' : args
}
If this function requires more than one argument, all should be
should be passed using the args list and appropriately handled.
"""
raise NotImplementedError(
"The TrafficController does not implement",
"the \"send_traffic_async\" function.")
def stop_traffic(self):
"""Kills traffic being sent from the traffic generator.
"""
self._logger.debug("stop_traffic()")
def print_results(self):
"""IResult interface implementation.
"""
counter = 0
for item in self._results:
logging.info("Record: " + str(counter))
counter += 1
for(key, value) in list(item.items()):
logging.info(" Key: " + str(key) +
", Value: " + str(value))
def get_results(self):
"""IResult interface implementation.
"""
return self._results
def validate_send_traffic(self, dummy_result, dummy_traffic):
"""Verify that send traffic has succeeded
"""
if len(self._results):
if 'b2b_frames' in self._results[-1]:
return float(self._results[-1]['b2b_frames']) > 0
elif 'throughput_rx_fps' in self._results[-1]:
return float(self._results[-1]['throughput_rx_fps']) > 0
else:
return True
else:
return False
|