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
|
d='n88' href='#n88'>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
|
#!/usr/bin/env python
# Copyright 2017 Cisco Systems, Inc. All rights reserved.
#
# 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.
#
import requests
import time
from socketIO_client import SocketIO
class TimeOutException(Exception):
pass
class NfvbenchException(Exception):
pass
class NfvbenchClient(object):
"""Python client class to control a nfvbench server
The nfvbench server must run in background using the --server option.
Since HTML pages are not required, the path to pass to --server can be
any directory on the host.
"""
def __init__(self, nfvbench_url, use_socketio):
"""Client class to send requests to the nfvbench server
Args:
nfvbench_url: the URL of the nfvbench server (e.g. 'http://127.0.0.1:7555')
"""
self.url = nfvbench_url
self.use_socketio = use_socketio
def socketio_send(self, send_event, receive_event, config, timeout):
class Exec(object):
socketIO = None
socketio_result = None
def close_socketio(result):
Exec.socketio_result = result
Exec.socketIO.disconnect()
def on_response(*args):
close_socketio(args[0])
def on_error(*args):
raise NfvbenchException(args[0])
Exec.socketIO = SocketIO(self.url)
Exec.socketIO.on(receive_event, on_response)
Exec.socketIO.on('error', on_error)
Exec.socketIO.emit(send_event, config)
Exec.socketIO.wait(seconds=timeout)
if timeout and not Exec.socketio_result:
raise TimeOutException()
return Exec.socketio_result
def http_get(self, command, config):
url = self.url + '/' + command
res = requests.get(url, json=config)
if res.ok:
return res.json()
res.raise_for_status()
def http_post(self, command, config):
url = self.url + '/' + command
res = requests.post(url, json=config)
if res.ok:
return res.json()
res.raise_for_status()
def echo_config(self, config, timeout=100):
"""Send an echo event to the nfvbench server with some dummy config and expect the
config to be sent back right away.
Args:
config: some dummy configuration - must be a valid dict
timeout: how long to wait in seconds or 0 to return immediately,
defaults to 100 seconds
Returns:
The config as passed as a dict or None if timeout passed is 0
Raises:
NfvbenchException: the execution of the passed configuration failed,
the body of the exception
containes the description of the failure.
TimeOutException: the request timed out (and might still being executed
by the server)
"""
if self.use_socketio:
return self.socketio_send('echo', 'echo', config, timeout)
return self.http_get('echo', config)
def run_config(self, config, timeout=300, poll_interval=5):
"""Request an nfvbench configuration to be executed by the nfvbench server.
This function will block the caller until the request completes or the request times out.
It can return immediately if timeout is set to 0.
Note that running a configuration may take a while depending on the amount of work
requested - so set the timeout value to an appropriate value.
Args:
config: the nfvbench configuration to execute - must be a valid dict with
valid nfvbench attributes
timeout: how long to wait in seconds or 0 to return immediately,
defaults to 300 seconds
poll_interval: seconds between polling (http only) - defaults to every 5 seconds
Returns:
The result of the nfvbench execution
or None if timeout passed is 0
The function will return as soon as the request is completed or when the
timeout occurs (whichever is first).
Raises:
NfvbenchException: the execution of the passed configuration failed, the body of
the exception contains the description of the failure.
TimeOutException: the request timed out but will still be executed by the server.
"""
if self.use_socketio:
return self.socketio_send('start_run', 'run_end', config, timeout)
res = self.http_post('start_run', config)
if res['status'] != 'PENDING':
raise NfvbenchException(res['error_message'])
# poll until request completes
elapsed = 0
while True:
time.sleep(poll_interval)
result = self.http_get('status', config)
if result['status'] != 'PENDING':
return result
elapsed += poll_interval
if elapsed >= timeout:
raise TimeOutException()
|