diff options
Diffstat (limited to 'client/client.py')
-rw-r--r-- | client/client.py | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/client/client.py b/client/client.py new file mode 100644 index 0000000..5cbc733 --- /dev/null +++ b/client/client.py @@ -0,0 +1,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() |