2 # Copyright 2017 Cisco Systems, Inc. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
20 from socketIO_client import SocketIO
23 class TimeOutException(Exception):
27 class NfvbenchException(Exception):
31 class NfvbenchClient(object):
32 """Python client class to control a nfvbench server
34 The nfvbench server must run in background using the --server option.
35 Since HTML pages are not required, the path to pass to --server can be
36 any directory on the host.
38 def __init__(self, nfvbench_url, use_socketio):
39 """Client class to send requests to the nfvbench server
42 nfvbench_url: the URL of the nfvbench server (e.g. 'http://127.0.0.1:7555')
44 self.url = nfvbench_url
45 self.use_socketio = use_socketio
47 def socketio_send(self, send_event, receive_event, config, timeout):
50 socketio_result = None
52 def close_socketio(result):
53 Exec.socketio_result = result
54 Exec.socketIO.disconnect()
56 def on_response(*args):
57 close_socketio(args[0])
60 raise NfvbenchException(args[0])
62 Exec.socketIO = SocketIO(self.url)
63 Exec.socketIO.on(receive_event, on_response)
64 Exec.socketIO.on('error', on_error)
65 Exec.socketIO.emit(send_event, config)
66 Exec.socketIO.wait(seconds=timeout)
68 if timeout and not Exec.socketio_result:
69 raise TimeOutException()
70 return Exec.socketio_result
72 def http_get(self, command, config):
73 url = self.url + '/' + command
74 res = requests.get(url, json=config)
77 res.raise_for_status()
79 def http_post(self, command, config):
80 url = self.url + '/' + command
81 res = requests.post(url, json=config)
84 res.raise_for_status()
86 def echo_config(self, config, timeout=100):
87 """Send an echo event to the nfvbench server with some dummy config and expect the
88 config to be sent back right away.
91 config: some dummy configuration - must be a valid dict
92 timeout: how long to wait in seconds or 0 to return immediately,
93 defaults to 100 seconds
96 The config as passed as a dict or None if timeout passed is 0
99 NfvbenchException: the execution of the passed configuration failed,
100 the body of the exception
101 containes the description of the failure.
102 TimeOutException: the request timed out (and might still being executed
105 if self.use_socketio:
106 return self.socketio_send('echo', 'echo', config, timeout)
107 return self.http_get('echo', config)
109 def run_config(self, config, timeout=300, poll_interval=5):
110 """Request an nfvbench configuration to be executed by the nfvbench server.
112 This function will block the caller until the request completes or the request times out.
113 It can return immediately if timeout is set to 0.
114 Note that running a configuration may take a while depending on the amount of work
115 requested - so set the timeout value to an appropriate value.
118 config: the nfvbench configuration to execute - must be a valid dict with
119 valid nfvbench attributes
120 timeout: how long to wait in seconds or 0 to return immediately,
121 defaults to 300 seconds
122 poll_interval: seconds between polling (http only) - defaults to every 5 seconds
125 The result of the nfvbench execution
126 or None if timeout passed is 0
127 The function will return as soon as the request is completed or when the
128 timeout occurs (whichever is first).
131 NfvbenchException: the execution of the passed configuration failed, the body of
132 the exception contains the description of the failure.
133 TimeOutException: the request timed out but will still be executed by the server.
135 if self.use_socketio:
136 return self.socketio_send('start_run', 'run_end', config, timeout)
137 res = self.http_post('start_run', config)
138 if res['status'] != 'PENDING':
139 raise NfvbenchException(res['error_message'])
141 # poll until request completes
144 time.sleep(poll_interval)
145 result = self.http_get('status', config)
146 if result['status'] != 'PENDING':
148 elapsed += poll_interval
149 if elapsed >= timeout:
150 raise TimeOutException()