Some PEP8 style fixes.

pull/21/head^2
grossmj 10 years ago
parent a39a693cda
commit 7b58f14681

@ -23,6 +23,7 @@ Sends version to requesting clients in JSON-RPC Websocket handler.
from ..version import __version__
from ..jsonrpc import JSONRPCResponse
def server_version(handler, request_id, params):
"""
Builtin destination to return the server version.

@ -38,15 +38,14 @@ class FileUploadHandler(tornado.web.RequestHandler):
:param request: Tornado Request instance
"""
def __init__(self, application, request):
def __init__(self, application, request, **kwargs):
# get the upload directory from the configuration file
super().__init__(application, request, **kwargs)
config = Config.instance()
server_config = config.get_default_section()
# default projects directory is "~/Documents/GNS3/images"
self._upload_dir = os.path.expandvars(os.path.expanduser(server_config.get("upload_directory", "~/Documents/GNS3/images")))
self._upload_dir = os.path.expandvars(
os.path.expanduser(server_config.get("upload_directory", "~/Documents/GNS3/images")))
self._host = request.host
try:
os.makedirs(self._upload_dir)
log.info("upload directory '{}' created".format(self._upload_dir))
@ -55,8 +54,6 @@ class FileUploadHandler(tornado.web.RequestHandler):
except OSError as e:
log.error("could not create the upload directory {}: {}".format(self._upload_dir, e))
tornado.websocket.WebSocketHandler.__init__(self, application, request)
def get(self):
"""
Invoked on GET request.

@ -106,8 +106,7 @@ class JSONRPCWebSocket(tornado.websocket.WebSocketHandler):
if destination.startswith("builtin"):
log.debug("registering {} as a built-in destination".format(destination))
else:
log.debug("registering {} as a destination for the {} module".format(destination,
module))
log.debug("registering {} as a destination for the {} module".format(destination, module))
cls.destinations[destination] = module
def open(self):

@ -161,7 +161,7 @@ class JSONRPCRequest(JSONRPCObject):
def __init__(self, method, params=None, request_id=None):
JSONRPCObject.__init__(self)
if request_id == None:
if request_id is None:
request_id = str(uuid.uuid4())
self.id = request_id
self.method = method

@ -15,7 +15,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import imp
import inspect
import pkgutil
from .modules import IModule

@ -96,7 +96,7 @@ def wait_socket_is_ready(host, port, wait=2.0, socket_timeout=10):
connection_success = False
begin = time.time()
last_exception = None
while (time.time() - begin < wait):
while time.time() - begin < wait:
time.sleep(0.01)
try:
with socket.create_connection((host, port), socket_timeout):
@ -107,16 +107,15 @@ def wait_socket_is_ready(host, port, wait=2.0, socket_timeout=10):
connection_success = True
break
return (connection_success, last_exception)
return connection_success, last_exception
def has_privileged_access(executable, device):
def has_privileged_access(executable):
"""
Check if an executable can access Ethernet and TAP devices in
RAW mode.
:param executable: executable path
:param device: device name
:returns: True or False
"""

@ -288,7 +288,7 @@ class IModule(multiprocessing.Process):
"""
# check if we have a request
if request == None:
if request is None:
self.send_param_error()
return False
log.debug("received request {}".format(request))

@ -27,7 +27,6 @@ import shutil
import glob
import socket
from gns3server.modules import IModule
import gns3server.jsonrpc as jsonrpc
from .hypervisor import Hypervisor
from .hypervisor_manager import HypervisorManager
@ -249,8 +248,8 @@ class Dynamips(IModule):
if not os.access(self._dynamips, os.X_OK):
raise DynamipsError("Dynamips {} is not executable".format(self._dynamips))
try:
workdir = os.path.join(self._working_dir, "dynamips")
try:
os.makedirs(workdir)
except FileExistsError:
pass
@ -282,7 +281,7 @@ class Dynamips(IModule):
:param request: JSON request
"""
if request == None:
if request is None:
self.send_param_error()
return
@ -342,7 +341,7 @@ class Dynamips(IModule):
:param request: JSON request
"""
if request == None:
if request is None:
self.send_param_error()
else:
log.debug("received request {}".format(request))
@ -415,7 +414,6 @@ class Dynamips(IModule):
port,
host))
response = {"lport": port}
return response
def set_ghost_ios(self, router):
@ -498,7 +496,7 @@ class Dynamips(IModule):
"""
log.info("creating config file {} from base64".format(destination_config_path))
config = base64.decodestring(config_base64.encode("utf-8")).decode("utf-8")
config = base64.decodebytes(config_base64.encode("utf-8")).decode("utf-8")
config = "!\n" + config.replace("\r", "")
config = config.replace('%h', router.name)
config_dir = os.path.dirname(destination_config_path)

@ -63,7 +63,7 @@ class Adapter(object):
False otherwise.
"""
if self._wics[wic_slot_id] == None:
if self._wics[wic_slot_id] is None:
return True
return False

@ -61,7 +61,7 @@ class DynamipsHypervisor(object):
self._udp_end_port_range = 20000
self._nio_udp_auto_instances = {}
self._version = "N/A"
self._timeout = 30
self._timeout = timeout
self._socket = None
self._uuid = None
@ -80,9 +80,7 @@ class DynamipsHypervisor(object):
host = self._host
try:
self._socket = socket.create_connection((host,
self._port),
self._timeout)
self._socket = socket.create_connection((host, self._port), self._timeout)
except OSError as e:
raise DynamipsError("Could not connect to server: {}".format(e))

@ -70,7 +70,7 @@ class Hypervisor(DynamipsHypervisor):
:returns: id (integer)
"""
return(self._id)
return self._id
@property
def started(self):
@ -90,7 +90,7 @@ class Hypervisor(DynamipsHypervisor):
:returns: path to Dynamips
"""
return(self._path)
return self._path
@path.setter
def path(self, path):
@ -110,7 +110,7 @@ class Hypervisor(DynamipsHypervisor):
:returns: port number (integer)
"""
return(self._port)
return self._port
@port.setter
def port(self, port):
@ -130,7 +130,7 @@ class Hypervisor(DynamipsHypervisor):
:returns: host/address (string)
"""
return(self._host)
return self._host
@host.setter
def host(self, host):
@ -232,7 +232,7 @@ class Hypervisor(DynamipsHypervisor):
self._process.wait(1)
except subprocess.TimeoutExpired:
self._process.kill()
if self._process.poll() == None:
if self._process.poll() is None:
log.warn("Dynamips process {} is still running".format(self._process.pid))
if self._stdout_file and os.access(self._stdout_file, os.W_OK):
@ -264,7 +264,7 @@ class Hypervisor(DynamipsHypervisor):
:returns: True or False
"""
if self._process and self._process.poll() == None:
if self._process and self._process.poll() is None:
return True
return False

@ -39,10 +39,6 @@ class HypervisorManager(object):
:param path: path to the Dynamips executable
:param working_dir: path to a working directory
:param host: host/address for hypervisors to listen to
:param base_port: base TCP port for hypervisors
:param base_console: base TCP port for consoles
:param base_aux: base TCP port for auxiliary consoles
:param base_udp: base UDP port for UDP tunnels
"""
def __init__(self, path, working_dir, host='127.0.0.1'):
@ -504,13 +500,12 @@ class HypervisorManager(object):
else:
log.info("allocating an hypervisor per IOS image disabled")
def wait_for_hypervisor(self, host, port, timeout=10):
def wait_for_hypervisor(self, host, port):
"""
Waits for an hypervisor to be started (accepting a socket connection)
:param host: host/address to connect to the hypervisor
:param port: port to connect to the hypervisor
:param timeout: timeout value (default is 10 seconds)
"""
begin = time.time()

@ -174,7 +174,7 @@ class NIO(object):
:returns: tuple (filter name, filter options)
"""
return (self._input_filter, self._input_filter_options)
return self._input_filter, self._input_filter_options
@property
def output_filter(self):
@ -184,7 +184,7 @@ class NIO(object):
:returns: tuple (filter name, filter options)
"""
return (self._output_filter, self._output_filter_options)
return self._output_filter, self._output_filter_options
def get_stats(self):
"""

@ -20,8 +20,6 @@ Interface for Dynamips NIO bridge module ("nio_bridge").
http://github.com/GNS3/dynamips/blob/master/README.hypervisor#L538
"""
from ..dynamips_error import DynamipsError
class Bridge(object):
"""

@ -250,7 +250,6 @@ class Router(object):
raise DynamipsError("Could not amend the configuration {}: {}".format(private_config_path, e))
self.set_config(self.startup_config, new_private_config_path)
new_name_no_quotes = new_name
new_name = '"' + new_name + '"' # put the new name into quotes to protect spaces
self._hypervisor.send("vm rename {name} {new_name}".format(name=self._name,
new_name=new_name))
@ -978,7 +977,7 @@ class Router(object):
translated by the JIT (they contain the native code
corresponding to MIPS code pages).
:param excec_area: exec area value (integer)
:param exec_area: exec area value (integer)
"""
self._hypervisor.send("vm set_exec_area {name} {exec_area}".format(name=self._name,
@ -1259,7 +1258,7 @@ class Router(object):
:returns: slot bindings (adapter names) list
"""
return (self._hypervisor.send("vm slot_bindings {}".format(self._name)))
return self._hypervisor.send("vm slot_bindings {}".format(self._name))
def slot_add_binding(self, slot_id, adapter):
"""
@ -1275,15 +1274,15 @@ class Router(object):
raise DynamipsError("Slot {slot_id} doesn't exist on router {name}".format(name=self._name,
slot_id=slot_id))
if slot != None:
if slot is not None:
current_adapter = slot
raise DynamipsError("Slot {slot_id} is already occupied by adapter {adapter} on router {name}".format(name=self._name,
slot_id=slot_id,
adapter=current_adapter))
# Only c7200, c3600 and c3745 (NM-4T only) support new adapter while running
if self.is_running() and not (self._platform == 'c7200' \
and not (self._platform == 'c3600' and self.chassis == '3660') \
if self.is_running() and not (self._platform == 'c7200'
and not (self._platform == 'c3600' and self.chassis == '3660')
and not (self._platform == 'c3745' and adapter == 'NM-4T')):
raise DynamipsError("Adapter {adapter} cannot be added while router {name} is running".format(adapter=adapter,
name=self._name))
@ -1322,13 +1321,13 @@ class Router(object):
raise DynamipsError("Slot {slot_id} doesn't exist on router {name}".format(name=self._name,
slot_id=slot_id))
if adapter == None:
if adapter is None:
raise DynamipsError("No adapter in slot {slot_id} on router {name}".format(name=self._name,
slot_id=slot_id))
# Only c7200, c3600 and c3745 (NM-4T only) support to remove adapter while running
if self.is_running() and not (self._platform == 'c7200' \
and not (self._platform == 'c3600' and self.chassis == '3660') \
if self.is_running() and not (self._platform == 'c7200'
and not (self._platform == 'c3600' and self.chassis == '3660')
and not (self._platform == 'c3745' and adapter == 'NM-4T')):
raise DynamipsError("Adapter {adapter} cannot be removed while router {name} is running".format(adapter=adapter,
name=self._name))

@ -20,17 +20,13 @@ IOU server module.
"""
import os
import sys
import base64
import tempfile
import fcntl
import struct
import socket
import shutil
from gns3server.modules import IModule
from gns3server.config import Config
import gns3server.jsonrpc as jsonrpc
from .iou_device import IOUDevice
from .iou_error import IOUError
from .nios.nio_udp import NIO_UDP
@ -215,12 +211,12 @@ class IOU(IModule):
:param request: JSON request
"""
if request == None:
if request is None:
self.send_param_error()
return
if "iourc" in request:
iourc_content = base64.decodestring(request["iourc"].encode("utf-8")).decode("utf-8")
iourc_content = base64.decodebytes(request["iourc"].encode("utf-8")).decode("utf-8")
iourc_content = iourc_content.replace("\r\n", "\n") # dos2unix
try:
with tempfile.NamedTemporaryFile(mode="w", delete=False) as f:
@ -228,7 +224,7 @@ class IOU(IModule):
f.write(iourc_content)
self._iourc = f.name
except OSError as e:
raise IOUError("Could not save iourc file to {}: {}".format(f.name, e))
raise IOUError("Could not create the iourc file: {}".format(e))
if "iouyap" in request and request["iouyap"]:
self._iouyap = request["iouyap"]
@ -410,7 +406,7 @@ class IOU(IModule):
try:
if "startup_config_base64" in request:
# a new startup-config has been pushed
config = base64.decodestring(request["startup_config_base64"].encode("utf-8")).decode("utf-8")
config = base64.decodebytes(request["startup_config_base64"].encode("utf-8")).decode("utf-8")
config = "!\n" + config.replace("\r", "")
config = config.replace('%h', iou_instance.name)
try:
@ -587,8 +583,8 @@ class IOU(IModule):
iou_instance.id,
port,
self._host))
response = {"lport": port}
response["port_id"] = request["port_id"]
response = {"lport": port,
"port_id": request["port_id"]}
self.send_response(response)
@IModule.route("iou.add_nio")
@ -643,12 +639,12 @@ class IOU(IModule):
nio = NIO_UDP(lport, rhost, rport)
elif request["nio"]["type"] == "nio_tap":
tap_device = request["nio"]["tap_device"]
if not has_privileged_access(self._iouyap, tap_device):
if not has_privileged_access(self._iouyap):
raise IOUError("{} has no privileged access to {}.".format(self._iouyap, tap_device))
nio = NIO_TAP(tap_device)
elif request["nio"]["type"] == "nio_generic_ethernet":
ethernet_device = request["nio"]["ethernet_device"]
if not has_privileged_access(self._iouyap, ethernet_device):
if not has_privileged_access(self._iouyap):
raise IOUError("{} has no privileged access to {}.".format(self._iouyap, ethernet_device))
nio = NIO_GenericEthernet(ethernet_device)
if not nio:
@ -710,7 +706,7 @@ class IOU(IModule):
:param request: JSON request
"""
if request == None:
if request is None:
self.send_param_error()
else:
log.debug("received request {}".format(request))

@ -83,7 +83,7 @@ class IOUDevice(object):
self._iourc = ""
self._iouyap = ""
self._console = console
self._working_dir = None
self._working_dir = working_dir
self._command = []
self._process = None
self._iouyap_process = None
@ -154,7 +154,7 @@ class IOUDevice(object):
:returns: id (integer)
"""
return(self._id)
return self._id
@classmethod
def reset(cls):
@ -185,7 +185,7 @@ class IOUDevice(object):
if self._startup_config:
# update the startup-config
config_path = os.path.join(self.working_dir, "startup-config")
config_path = os.path.join(self._working_dir, "startup-config")
if os.path.isfile(config_path):
try:
with open(config_path, "r+") as f:
@ -209,7 +209,7 @@ class IOUDevice(object):
:returns: path to IOU
"""
return(self._path)
return self._path
@path.setter
def path(self, path):
@ -232,14 +232,14 @@ class IOUDevice(object):
:returns: path to the iourc file
"""
return(self._iourc)
return self._iourc
@iourc.setter
def iourc(self, iourc):
"""
Sets the path to the iourc file.
:param path: path to the iourc file.
:param iourc: path to the iourc file.
"""
self._iourc = iourc
@ -255,14 +255,14 @@ class IOUDevice(object):
:returns: path to iouyap
"""
return(self._iouyap)
return self._iouyap
@iouyap.setter
def iouyap(self, iouyap):
"""
Sets the path to iouyap.
:param path: path to iouyap
:param iouyap: path to iouyap
"""
self._iouyap = iouyap
@ -402,6 +402,7 @@ class IOUDevice(object):
for unit in adapter.ports.keys():
nio = adapter.get_nio(unit)
if nio:
connection = None
if isinstance(nio, NIO_UDP):
# UDP tunnel
connection = {"tunnel_udp": "{lport}:{rhost}:{rport}".format(lport=nio.lport,
@ -415,6 +416,7 @@ class IOUDevice(object):
# Ethernet interface
connection = {"eth_dev": "{ethernet_device}".format(ethernet_device=nio.ethernet_device)}
if connection:
config["{iouyap_id}:{bay}/{unit}".format(iouyap_id=str(self._id + 512), bay=bay_id, unit=unit_id)] = connection
unit_id += 1
bay_id += 1
@ -581,7 +583,7 @@ class IOUDevice(object):
self._iouyap_process.wait(1)
except subprocess.TimeoutExpired:
self._iouyap_process.kill()
if self._iouyap_process.poll() == None:
if self._iouyap_process.poll() is None:
log.warn("iouyap PID={} for IOU instance {} is still running".format(self._iouyap_process.pid,
self._id))
self._iouyap_process = None
@ -594,7 +596,7 @@ class IOUDevice(object):
self._process.wait(1)
except subprocess.TimeoutExpired:
self._process.kill()
if self._process.poll() == None:
if self._process.poll() is None:
log.warn("IOU instance {} PID={} is still running".format(self._id,
self._process.pid))
self._process = None
@ -637,7 +639,7 @@ class IOUDevice(object):
:returns: True or False
"""
if self._process and self._process.poll() == None:
if self._process and self._process.poll() is None:
return True
return False
@ -648,7 +650,7 @@ class IOUDevice(object):
:returns: True or False
"""
if self._iouyap_process and self._iouyap_process.poll() == None:
if self._iouyap_process and self._iouyap_process.poll() is None:
return True
return False
@ -723,16 +725,14 @@ class IOUDevice(object):
env = os.environ.copy()
env["IOURC"] = self._iourc
output = b""
try:
output = subprocess.check_output([self._path, "-h"], stderr=subprocess.STDOUT, cwd=self._working_dir, env=env)
except OSError as e:
log.warn("could not determine if layer 1 keepalive messages are supported by {}: {}".format(os.path.basename(self._path), e))
else:
if re.search("-l\s+Enable Layer 1 keepalive messages", output.decode("utf-8")):
command.extend(["-l"])
else:
raise IOUError("layer 1 keepalive messages are not supported by {}".format(os.path.basename(self._path)))
except OSError as e:
log.warn("could not determine if layer 1 keepalive messages are supported by {}: {}".format(os.path.basename(self._path), e))
def _build_command(self):
"""

@ -56,7 +56,7 @@ EXIT_ABORT = 2
# Mostly from:
# https://code.google.com/p/miniboa/source/browse/trunk/miniboa/telnet.py
#--[ Telnet Commands ]---------------------------------------------------------
SE = 240 # End of subnegotiation parameters
SE = 240 # End of sub-negotiation parameters
NOP = 241 # No operation
DATMK = 242 # Data stream portion of a sync.
BREAK = 243 # NVT Character BRK
@ -299,9 +299,7 @@ class TelnetServer(Console):
buf.extend(self._read_block(1))
iac_cmd.append(buf[iac_loc + 2])
# We do ECHO, SGA, and BINARY. Period.
if (iac_cmd[1] == DO
and iac_cmd[2] not in [ECHO, SGA, BINARY]):
if iac_cmd[1] == DO and iac_cmd[2] not in [ECHO, SGA, BINARY]:
self._write_cur(bytes([IAC, WONT, iac_cmd[2]]))
log.debug("Telnet WON'T {:#x}".format(iac_cmd[2]))
else:
@ -601,7 +599,7 @@ def start_ioucon(cmdline_args, stop_event):
nport = int(port)
except ValueError:
pass
if (addr == '' or nport == 0):
if addr == '' or nport == 0:
raise ConfigError('format for --telnet-server must be '
'ADDR:PORT (like 127.0.0.1:20000)')

@ -20,16 +20,12 @@ VPCS server module.
"""
import os
import sys
import base64
import tempfile
import struct
import socket
import shutil
from gns3server.modules import IModule
from gns3server.config import Config
import gns3server.jsonrpc as jsonrpc
from .vpcs_device import VPCSDevice
from .vpcs_error import VPCSError
from .nios.nio_udp import NIO_UDP
@ -101,7 +97,6 @@ class VPCS(IModule):
:param signum: signal number (if called by the signal handler)
"""
# self._vpcs_callback.stop()
# delete all VPCS instances
for vpcs_id in self._vpcs_instances:
vpcs_instance = self._vpcs_instances[vpcs_id]
@ -162,7 +157,7 @@ class VPCS(IModule):
:param request: JSON request
"""
if request == None:
if request is None:
self.send_param_error()
return
@ -326,7 +321,7 @@ class VPCS(IModule):
try:
if "script_file_base64" in request:
# a new startup-config has been pushed
config = base64.decodestring(request["script_file_base64"].encode("utf-8")).decode("utf-8")
config = base64.decodebytes(request["script_file_base64"].encode("utf-8")).decode("utf-8")
config = config.replace("\r", "")
config = config.replace('%h', vpcs_instance.name)
try:
@ -502,8 +497,8 @@ class VPCS(IModule):
port,
self._host))
response = {"lport": port}
response["port_id"] = request["port_id"]
response = {"lport": port,
"port_id": request["port_id"]}
self.send_response(response)
@IModule.route("vpcs.add_nio")
@ -554,7 +549,7 @@ class VPCS(IModule):
nio = NIO_UDP(lport, rhost, rport)
elif request["nio"]["type"] == "nio_tap":
tap_device = request["nio"]["tap_device"]
if not self.has_privileged_access(self._vpcs, tap_device):
if not self.has_privileged_access(self._vpcs):
raise VPCSError("{} has no privileged access to {}.".format(self._vpcs, tap_device))
nio = NIO_TAP(tap_device)
if not nio:
@ -614,7 +609,7 @@ class VPCS(IModule):
:param request: JSON request
"""
if request == None:
if request is None:
self.send_param_error()
else:
log.debug("received request {}".format(request))

@ -81,7 +81,8 @@ class VPCSDevice(object):
self._path = path
self._console = console
self._working_dir = None
self._working_dir = working_dir
self._host = host
self._command = []
self._process = None
self._vpcs_stdout_file = ""
@ -135,7 +136,7 @@ class VPCSDevice(object):
:returns: id (integer)
"""
return(self._id)
return self._id
@classmethod
def reset(cls):
@ -166,7 +167,7 @@ class VPCSDevice(object):
if self._script_file:
# update the startup.vpc
config_path = os.path.join(self.working_dir, "startup.vpc")
config_path = os.path.join(self._working_dir, "startup.vpc")
if os.path.isfile(config_path):
try:
with open(config_path, "r+") as f:
@ -190,7 +191,7 @@ class VPCSDevice(object):
:returns: path to VPCS
"""
return(self._path)
return self._path
@path.setter
def path(self, path):
@ -331,10 +332,10 @@ class VPCSDevice(object):
raise VPCSError("No path to a VPCS executable has been set")
if not os.path.isfile(self._path):
raise VPCSError("VPCS '{}' is not accessible".format(self._path))
raise VPCSError("VPCS program '{}' is not accessible".format(self._path))
if not os.access(self._path, os.X_OK):
raise VPCSError("VPCS '{}' is not executable".format(self._path))
raise VPCSError("VPCS program '{}' is not executable".format(self._path))
if not self._ethernet_adapter.get_nio(0):
raise VPCSError("This VPCS instance must be connected in order to start")
@ -400,7 +401,7 @@ class VPCSDevice(object):
:returns: True or False
"""
if self._process and self._process.poll() == None:
if self._process and self._process.poll() is None:
return True
return False
@ -517,7 +518,7 @@ class VPCSDevice(object):
"""
Sets the script-file for this VPCS instance.
:param base_script_file: path to base-script-file
:param script_file: path to base-script-file
"""
self._script_file = script_file

@ -1,3 +1,4 @@
netifaces
tornado
pyzmq
netifaces-py3

@ -40,7 +40,7 @@ class JSONRPC(AsyncTestCase):
AsyncWSRequest(self.URL, self.io_loop, self.stop, json_encode(request))
response = self.wait()
json_response = json_decode(response)
assert json_response["id"] == None
assert json_response["id"] is None
assert json_response["error"].get("code") == -32600
def test_request_with_invalid_json(self):
@ -49,7 +49,7 @@ class JSONRPC(AsyncTestCase):
AsyncWSRequest(self.URL, self.io_loop, self.stop, request)
response = self.wait()
json_response = json_decode(response)
assert json_response["id"] == None
assert json_response["id"] is None
assert json_response["error"].get("code") == -32700
def test_request_with_invalid_jsonrpc_field(self):
@ -58,7 +58,7 @@ class JSONRPC(AsyncTestCase):
AsyncWSRequest(self.URL, self.io_loop, self.stop, json_encode(request))
response = self.wait()
json_response = json_decode(response)
assert json_response["id"] == None
assert json_response["id"] is None
assert json_response["error"].get("code") == -32700
def test_request_with_no_params(self):

@ -34,7 +34,7 @@ class TestVersionHandler(AsyncHTTPTestCase):
self.http_client.fetch(self.get_url(self.URL), self.stop)
response = self.wait()
assert(response.headers['Content-Type'].startswith('application/json'))
assert(response.body)
assert response.headers['Content-Type'].startswith('application/json')
assert response.body
body = json_decode(response.body)
assert body['version'] == __version__

Loading…
Cancel
Save