behave_tests: refactor TestAPI HTTP request
[nfvbench.git] / client / client.py
1 #!/usr/bin/env python
2 # Copyright 2017 Cisco Systems, Inc.  All rights reserved.
3 #
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
7 #
8 #         http://www.apache.org/licenses/LICENSE-2.0
9 #
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
14 #    under the License.
15 #
16
17 import requests
18 import time
19
20
21 class TimeOutException(Exception):
22     pass
23
24
25 class NfvbenchException(Exception):
26     pass
27
28
29 class NfvbenchClient(object):
30     """Python client class to control a nfvbench server
31
32     The nfvbench server must run in background using the --server option.
33     """
34     def __init__(self, nfvbench_url):
35         """Client class to send requests to the nfvbench server
36
37         Args:
38             nfvbench_url: the URL of the nfvbench server (e.g. 'http://127.0.0.1:7555')
39         """
40         self.url = nfvbench_url
41
42     def http_get(self, command, config):
43         url = self.url + '/' + command
44         res = requests.get(url, json=config)
45         if res.ok:
46             return res.json()
47         res.raise_for_status()
48
49     def http_post(self, command, config):
50         url = self.url + '/' + command
51         res = requests.post(url, json=config)
52         if res.ok:
53             return res.json()
54         res.raise_for_status()
55
56     def echo_config(self, config, timeout=100):
57         """Send an echo event to the nfvbench server with some dummy config and expect the
58         config to be sent back right away.
59
60         Args:
61             config: some dummy configuration - must be a valid dict
62             timeout: how long to wait in seconds or 0 to return immediately,
63                      defaults to 100 seconds
64
65         Returns:
66             The config as passed as a dict or None if timeout passed is 0
67
68         Raises:
69             NfvbenchException: the execution of the passed configuration failed,
70                                the body of the exception
71                                containes the description of the failure.
72             TimeOutException: the request timed out (and might still being executed
73                               by the server)
74         """
75         return self.http_get('echo', config)
76
77     def run_config(self, config, timeout=300, poll_interval=5):
78         """Request an nfvbench configuration to be executed by the nfvbench server.
79
80         This function will block the caller until the request completes or the request times out.
81         It can return immediately if timeout is set to 0.
82         Note that running a configuration may take a while depending on the amount of work
83         requested - so set the timeout value to an appropriate value.
84
85         Args:
86             config: the nfvbench configuration to execute - must be a valid dict with
87                     valid nfvbench attributes
88             timeout: how long to wait in seconds or 0 to return immediately,
89                      defaults to 300 seconds
90             poll_interval: seconds between polling (http only) - defaults to every 5 seconds
91
92         Returns:
93             The result of the nfvbench execution
94             or None if timeout passed is 0
95             The function will return as soon as the request is completed or when the
96             timeout occurs (whichever is first).
97
98         Raises:
99             NfvbenchException: the execution of the passed configuration failed, the body of
100                                the exception contains the description of the failure.
101             TimeOutException: the request timed out but will still be executed by the server.
102         """
103         res = self.http_post('start_run', config)
104         if res['status'] != 'PENDING':
105             raise NfvbenchException(res['error_message'])
106
107         # poll until request completes
108         elapsed = 0
109         while True:
110             time.sleep(poll_interval)
111             result = self.http_get('status', config)
112             if result['status'] != 'PENDING':
113                 return result
114             elapsed += poll_interval
115             if elapsed >= timeout:
116                 raise TimeOutException()