Merge "test_kubernetes: mock file operations in test_ssh_key"
[yardstick.git] / yardstick / network_services / vnf_generic / vnf / base.py
1 # Copyright (c) 2016-2017 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 """ Base class implementation for generic vnf implementation """
15
16 from __future__ import absolute_import
17 import logging
18
19 LOG = logging.getLogger(__name__)
20
21
22 class QueueFileWrapper(object):
23     """ Class providing file-like API for talking with SSH connection """
24
25     def __init__(self, q_in, q_out, prompt):
26         self.q_in = q_in
27         self.q_out = q_out
28         self.closed = False
29         self.buf = []
30         self.bufsize = 20
31         self.prompt = prompt
32
33     def read(self, size):
34         """ read chunk from input queue """
35         if self.q_in.qsize() > 0 and size:
36             in_data = self.q_in.get()
37             return in_data
38
39     def write(self, chunk):
40         """ write chunk to output queue """
41         self.buf.append(chunk)
42         # flush on prompt or if we exceed bufsize
43
44         size = sum(len(c) for c in self.buf)
45         if self.prompt in chunk or size > self.bufsize:
46             out = ''.join(self.buf)
47             self.buf = []
48             self.q_out.put(out)
49
50     def close(self):
51         """ close multiprocessing queue """
52         pass
53
54     def clear(self):
55         """ clear queue """
56         while self.q_out.qsize() > 0:
57             self.q_out.get()
58
59
60 class VnfdHelper(dict):
61
62     @property
63     def mgmt_interface(self):
64         return self["mgmt-interface"]
65
66     @property
67     def vdu(self):
68         return self['vdu']
69
70     @property
71     def vdu0(self):
72         return self.vdu[0]
73
74     @property
75     def interfaces(self):
76         return self.vdu0['external-interface']
77
78     @property
79     def kpi(self):
80         return self['benchmark']['kpi']
81
82     def find_virtual_interface(self, **kwargs):
83         key, value = next(iter(kwargs.items()))
84         for interface in self.interfaces:
85             virtual_intf = interface["virtual-interface"]
86             if virtual_intf[key] == value:
87                 return interface
88
89     def find_interface(self, **kwargs):
90         key, value = next(iter(kwargs.items()))
91         for interface in self.interfaces:
92             if interface[key] == value:
93                 return interface
94
95
96 class VNFObject(object):
97
98     def __init__(self, name, vnfd):
99         super(VNFObject, self).__init__()
100         self.name = name
101         self.vnfd_helper = VnfdHelper(vnfd)  # fixme: parse this into a structure
102
103
104 class GenericVNF(VNFObject):
105
106     """ Class providing file-like API for generic VNF implementation """
107     def __init__(self, name, vnfd):
108         super(GenericVNF, self).__init__(name, vnfd)
109         # List of statistics we can obtain from this VNF
110         # - ETSI MANO 6.3.1.1 monitoring_parameter
111         self.kpi = self._get_kpi_definition()
112         # Standard dictionary containing params like thread no, buffer size etc
113         self.config = {}
114         self.runs_traffic = False
115
116     def _get_kpi_definition(self):
117         """ Get list of KPIs defined in VNFD
118
119         :param vnfd:
120         :return: list of KPIs, e.g. ['throughput', 'latency']
121         """
122         return self.vnfd_helper.kpi
123
124     def instantiate(self, scenario_cfg, context_cfg):
125         """ Prepare VNF for operation and start the VNF process/VM
126
127         :param scenario_cfg:
128         :param context_cfg:
129         :return: True/False
130         """
131         raise NotImplementedError()
132
133     def terminate(self):
134         """ Kill all VNF processes
135
136         :return:
137         """
138         raise NotImplementedError()
139
140     def scale(self, flavor=""):
141         """
142
143         :param flavor:
144         :return:
145         """
146         raise NotImplementedError()
147
148     def collect_kpi(self):
149         """This method should return a dictionary containing the
150         selected KPI at a given point of time.
151
152         :return: {"kpi": value, "kpi2": value}
153         """
154         raise NotImplementedError()
155
156
157 class GenericTrafficGen(GenericVNF):
158     """ Class providing file-like API for generic traffic generator """
159
160     def __init__(self, name, vnfd):
161         super(GenericTrafficGen, self).__init__(name, vnfd)
162         self.runs_traffic = True
163         self.traffic_finished = False
164
165     def run_traffic(self, traffic_profile):
166         """ Generate traffic on the wire according to the given params.
167         Method is non-blocking, returns immediately when traffic process
168         is running. Mandatory.
169
170         :param traffic_profile:
171         :return: True/False
172         """
173         raise NotImplementedError()
174
175     def listen_traffic(self, traffic_profile):
176         """ Listen to traffic with the given parameters.
177         Method is non-blocking, returns immediately when traffic process
178         is running. Optional.
179
180         :param traffic_profile:
181         :return: True/False
182         """
183         pass
184
185     def verify_traffic(self, traffic_profile):
186         """ Verify captured traffic after it has ended. Optional.
187
188         :param traffic_profile:
189         :return: dict
190         """
191         pass
192
193     def terminate(self):
194         """ After this method finishes, all traffic processes should stop. Mandatory.
195
196         :return: True/False
197         """
198         raise NotImplementedError()