1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-12-25 00:08:11 +00:00

Fix tests to work with new version of aiohttp (>= 3.0)

This commit is contained in:
grossmj 2018-10-17 17:32:10 +07:00
parent 9ae9209881
commit ab8dc52ece
18 changed files with 218 additions and 184 deletions

View File

@ -96,9 +96,9 @@ class Compute:
return self._http_session
#def __del__(self):
# pass
# if self._http_session:
# self._http_session.close()
#
# if self._http_session:
# self._http_session.close()
def _set_auth(self, user, password):
"""
@ -415,7 +415,7 @@ class Compute:
if "version" not in response.json:
msg = "The server {} is not a GNS3 server".format(self._id)
log.error(msg)
self._http_session.close()
await self._http_session.close()
raise aiohttp.web.HTTPConflict(text=msg)
self._capabilities = response.json
@ -430,13 +430,13 @@ class Compute:
if __version_info__[3] == 0:
# Stable release
log.error(msg)
self._http_session.close()
await self._http_session.close()
self._last_error = msg
raise aiohttp.web.HTTPConflict(text=msg)
elif parse_version(__version__)[:2] != parse_version(response.json["version"])[:2]:
# We don't allow different major version to interact even with dev build
log.error(msg)
self._http_session.close()
await self._http_session.close()
self._last_error = msg
raise aiohttp.web.HTTPConflict(text=msg)
else:

View File

@ -181,7 +181,7 @@ class ProjectHandler:
queue = project.get_listen_queue()
ProjectHandler._notifications_listening.setdefault(project.id, 0)
ProjectHandler._notifications_listening[project.id] += 1
response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
await response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
while True:
try:
(action, msg) = await asyncio.wait_for(queue.get(), 5)
@ -190,11 +190,11 @@ class ProjectHandler:
else:
msg = json.dumps({"action": action, "event": msg}, sort_keys=True)
log.debug("Send notification: %s", msg)
response.write(("{}\n".format(msg)).encode("utf-8"))
await response.write(("{}\n".format(msg)).encode("utf-8"))
except asyncio.futures.CancelledError as e:
break
except asyncio.futures.TimeoutError:
response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
await response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
project.stop_listen_queue(queue)
if project.id in ProjectHandler._notifications_listening:
ProjectHandler._notifications_listening[project.id] -= 1
@ -374,10 +374,9 @@ class ProjectHandler:
include_images = bool(int(request.json.get("include_images", "0")))
for data in project.export(include_images=include_images):
response.write(data)
await response.drain()
await response.write(data)
await response.write_eof()
#await response.write_eof() #FIXME: shound't be needed anymore
@Route.post(
r"/projects/{project_id}/import",

View File

@ -420,9 +420,8 @@ class NodeHandler:
response.content_type = "application/octet-stream"
response.enable_chunked_encoding()
await response.prepare(request)
response.write(res.body)
await response.write_eof()
await response.write(res.body)
# await response.write_eof() #FIXME: shound't be needed anymore
@Route.post(
r"/projects/{project_id}/nodes/{node_id}/files/{path:.+}",

View File

@ -52,10 +52,9 @@ class NotificationHandler:
while True:
try:
msg = await queue.get_json(5)
response.write(("{}\n".format(msg)).encode("utf-8"))
await response.write(("{}\n".format(msg)).encode("utf-8"))
except asyncio.futures.CancelledError:
break
await response.drain()
@Route.get(
r"/notifications/ws",

View File

@ -231,10 +231,9 @@ class ProjectHandler:
while True:
try:
msg = await queue.get_json(5)
response.write(("{}\n".format(msg)).encode("utf-8"))
await response.write(("{}\n".format(msg)).encode("utf-8"))
except asyncio.futures.CancelledError as e:
break
await response.drain()
if project.auto_close:
# To avoid trouble with client connecting disconnecting we sleep few seconds before checking
@ -313,10 +312,9 @@ class ProjectHandler:
await response.prepare(request)
for data in stream:
response.write(data)
await response.drain()
await response.write(data)
await response.write_eof()
#await response.write_eof() #FIXME: shound't be needed anymore
# Will be raise if you have no space left or permission issue on your temporary directory
# RuntimeError: something was wrong during the zip process
except (ValueError, OSError, RuntimeError) as e:

View File

@ -144,7 +144,7 @@ class Response(aiohttp.web.Response):
if not data:
break
await self.write(data)
await self.drain()
# await self.drain()
except FileNotFoundError:
raise aiohttp.web.HTTPNotFound()

View File

@ -200,9 +200,11 @@ def test_reload(loop, vm, fake_iou_bin):
def test_close(vm, port_manager, loop):
vm._start_ubridge = AsyncioMagicMock(return_value=True)
vm._ubridge_send = AsyncioMagicMock()
with asyncio_patch("gns3server.compute.iou.iou_vm.IOUVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
vm.start()
loop.run_until_complete(asyncio.ensure_future(vm.start()))
port = vm.console
loop.run_until_complete(asyncio.ensure_future(vm.close()))
# Raise an exception if the port is not free

View File

@ -150,7 +150,7 @@ def test_stop(loop, vm, running_subprocess_mock):
with asyncio_patch("gns3server.compute.qemu.QemuVM.start_wrap_console"):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process):
nio = Qemu.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
vm.adapter_add_nio_binding(0, nio)
loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(0, nio)))
loop.run_until_complete(asyncio.ensure_future(vm.start()))
assert vm.is_running()
loop.run_until_complete(asyncio.ensure_future(vm.stop()))

View File

@ -55,7 +55,7 @@ def test_vm_invalid_traceng_path(vm, manager, loop):
with patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._traceng_path", return_value="/tmp/fake/path/traceng"):
with pytest.raises(TraceNGError):
nio = manager.create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
vm.port_add_nio_binding(0, nio)
loop.run_until_complete(asyncio.ensure_future(vm.port_add_nio_binding(0, nio)))
loop.run_until_complete(asyncio.ensure_future(vm.start()))
assert vm.name == "test"
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0e"
@ -164,16 +164,18 @@ def test_add_nio_binding_udp(vm, async_run):
assert nio.lport == 4242
def test_port_remove_nio_binding(vm):
def test_port_remove_nio_binding(loop, vm):
nio = TraceNG.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
vm.port_add_nio_binding(0, nio)
vm.port_remove_nio_binding(0)
loop.run_until_complete(asyncio.ensure_future(vm.port_add_nio_binding(0, nio)))
loop.run_until_complete(asyncio.ensure_future(vm.port_remove_nio_binding(0)))
assert vm._ethernet_adapter.ports[0] is None
def test_close(vm, port_manager, loop):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
vm.start()
loop.run_until_complete(asyncio.ensure_future(vm.close()))
assert vm.is_running() is False
vm.ip_address = "192.168.1.1"
with patch("sys.platform", return_value="win"):
with asyncio_patch("gns3server.compute.traceng.traceng_vm.TraceNGVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
loop.run_until_complete(asyncio.ensure_future(vm.start("192.168.1.2")))
loop.run_until_complete(asyncio.ensure_future(vm.close()))
assert vm.is_running() is False

View File

@ -70,7 +70,7 @@ def test_vm_invalid_vpcs_version(loop, manager, vm):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.subprocess_check_output", return_value="Welcome to Virtual PC Simulator, version 0.1"):
with pytest.raises(VPCSError):
nio = manager.create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1", "filters": {}})
vm.port_add_nio_binding(0, nio)
loop.run_until_complete(asyncio.ensure_future(vm.port_add_nio_binding(0, nio)))
loop.run_until_complete(asyncio.ensure_future(vm._check_vpcs_version()))
assert vm.name == "test"
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
@ -80,7 +80,7 @@ def test_vm_invalid_vpcs_path(vm, manager, loop):
with patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._vpcs_path", return_value="/tmp/fake/path/vpcs"):
with pytest.raises(VPCSError):
nio = manager.create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
vm.port_add_nio_binding(0, nio)
loop.run_until_complete(asyncio.ensure_future(vm.port_add_nio_binding(0, nio)))
loop.run_until_complete(asyncio.ensure_future(vm.start()))
assert vm.name == "test"
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0e"
@ -220,17 +220,17 @@ def test_add_nio_binding_udp(vm, async_run):
@pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows")
def test_add_nio_binding_tap(vm, ethernet_device):
def test_add_nio_binding_tap(vm, ethernet_device, loop):
with patch("gns3server.compute.base_manager.BaseManager.has_privileged_access", return_value=True):
nio = VPCS.instance().create_nio({"type": "nio_tap", "tap_device": ethernet_device})
vm.port_add_nio_binding(0, nio)
loop.run_until_complete(asyncio.ensure_future(vm.port_add_nio_binding(0, nio)))
assert nio.tap_device == ethernet_device
def test_port_remove_nio_binding(vm):
def test_port_remove_nio_binding(vm, loop):
nio = VPCS.instance().create_nio({"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
vm.port_add_nio_binding(0, nio)
vm.port_remove_nio_binding(0)
loop.run_until_complete(asyncio.ensure_future(vm.port_add_nio_binding(0, nio)))
loop.run_until_complete(asyncio.ensure_future(vm.port_remove_nio_binding(0)))
assert vm._ethernet_adapter.ports[0] is None
@ -297,8 +297,10 @@ def test_change_name(vm, tmpdir):
def test_close(vm, port_manager, loop):
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
vm.start()
loop.run_until_complete(asyncio.ensure_future(vm.close()))
assert vm.is_running() is False
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM.start_wrap_console"):
loop.run_until_complete(asyncio.ensure_future(vm.start()))
loop.run_until_complete(asyncio.ensure_future(vm.close()))
assert vm.is_running() is False

View File

@ -20,9 +20,11 @@ import pytest
import socket
import asyncio
import tempfile
import weakref
import shutil
import os
import sys
import aiohttp
from aiohttp import web
from unittest.mock import patch
@ -75,6 +77,16 @@ def _get_unused_port():
return port
@pytest.fixture
async def client(aiohttp_client):
"""
Return an helper allowing you to call the server without any prefix
"""
app = web.Application()
for method, route, handler in Route.get_routes():
app.router.add_route(method, route, handler)
return await aiohttp_client(app)
@pytest.yield_fixture
def http_server(request, loop, port_manager, monkeypatch, controller):
"""A GNS3 server"""
@ -83,14 +95,20 @@ def http_server(request, loop, port_manager, monkeypatch, controller):
for method, route, handler in Route.get_routes():
app.router.add_route(method, route, handler)
# Keep a list of active websocket connections
app['websockets'] = weakref.WeakSet()
host = "127.0.0.1"
# We try multiple time. Because on Travis test can fail when because the port is taken by someone else
for i in range(0, 5):
port = _get_unused_port()
try:
srv = loop.create_server(app.make_handler(), host, port)
srv = loop.run_until_complete(srv)
runner = web.AppRunner(app)
loop.run_until_complete(runner.setup())
site = web.TCPSite(runner, host, port)
loop.run_until_complete(site.start())
except OSError:
pass
else:
@ -98,13 +116,17 @@ def http_server(request, loop, port_manager, monkeypatch, controller):
yield (host, port)
# close websocket connections
for ws in set(app['websockets']):
loop.run_until_complete(ws.close(code=aiohttp.WSCloseCode.GOING_AWAY, message='Server shutdown'))
loop.run_until_complete(controller.stop())
for module in MODULES:
instance = module.instance()
monkeypatch.setattr('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.close', lambda self: True)
loop.run_until_complete(instance.unload())
srv.close()
loop.run_until_complete(srv.wait_closed())
loop.run_until_complete(runner.cleanup())
@pytest.fixture

View File

@ -80,8 +80,8 @@ def test_compute_httpQuery(compute, async_run):
response = MagicMock()
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
response.status = 200
async_run(compute.post("/projects", {"a": "b"}))
async_run(compute.close())
mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data=b'{"a": "b"}', headers={'content-type': 'application/json'}, auth=None, chunked=None, timeout=20)
assert compute._auth is None
@ -94,6 +94,7 @@ def test_compute_httpQueryAuth(compute, async_run):
compute.user = "root"
compute.password = "toor"
async_run(compute.post("/projects", {"a": "b"}))
async_run(compute.close())
mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data=b'{"a": "b"}', headers={'content-type': 'application/json'}, auth=compute._auth, chunked=None, timeout=20)
assert compute._auth.login == "root"
assert compute._auth.password == "toor"
@ -112,7 +113,7 @@ def test_compute_httpQueryNotConnected(compute, controller, async_run):
assert compute._connected
assert compute._capabilities["version"] == __version__
controller.notification.controller_emit.assert_called_with("compute.updated", compute.__json__())
async_run(compute.close())
def test_compute_httpQueryNotConnectedGNS3vmNotRunning(compute, controller, async_run):
"""
@ -136,6 +137,7 @@ def test_compute_httpQueryNotConnectedGNS3vmNotRunning(compute, controller, asyn
assert compute._connected
assert compute._capabilities["version"] == __version__
controller.notification.controller_emit.assert_called_with("compute.updated", compute.__json__())
async_run(compute.close())
def test_compute_httpQueryNotConnectedInvalidVersion(compute, async_run):
@ -147,7 +149,7 @@ def test_compute_httpQueryNotConnectedInvalidVersion(compute, async_run):
with pytest.raises(aiohttp.web.HTTPConflict):
async_run(compute.post("/projects", {"a": "b"}))
mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=None, timeout=20)
async_run(compute.close())
def test_compute_httpQueryNotConnectedNonGNS3Server(compute, async_run):
compute._connected = False
@ -158,7 +160,7 @@ def test_compute_httpQueryNotConnectedNonGNS3Server(compute, async_run):
with pytest.raises(aiohttp.web.HTTPConflict):
async_run(compute.post("/projects", {"a": "b"}))
mock.assert_any_call("GET", "https://example.com:84/v2/compute/capabilities", headers={'content-type': 'application/json'}, data=None, auth=None, chunked=None, timeout=20)
async_run(compute.close())
def test_compute_httpQueryNotConnectedNonGNS3Server2(compute, async_run):
compute._connected = False
@ -178,6 +180,7 @@ def test_compute_httpQueryError(compute, async_run):
with pytest.raises(aiohttp.web.HTTPNotFound):
async_run(compute.post("/projects", {"a": "b"}))
async_run(compute.close())
def test_compute_httpQueryConflictError(compute, async_run):
@ -188,7 +191,7 @@ def test_compute_httpQueryConflictError(compute, async_run):
with pytest.raises(ComputeConflict):
async_run(compute.post("/projects", {"a": "b"}))
async_run(compute.close())
def test_compute_httpQuery_project(compute, async_run):
response = MagicMock()
@ -198,69 +201,69 @@ def test_compute_httpQuery_project(compute, async_run):
project = Project(name="Test")
async_run(compute.post("/projects", project))
mock.assert_called_with("POST", "https://example.com:84/v2/compute/projects", data=json.dumps(project.__json__()), headers={'content-type': 'application/json'}, auth=None, chunked=None, timeout=20)
async_run(compute.close())
def test_connectNotification(compute, async_run):
ws_mock = AsyncioMagicMock()
call = 0
async def receive():
nonlocal call
call += 1
if call == 1:
response = MagicMock()
response.data = '{"action": "test", "event": {"a": 1}}'
response.tp = aiohttp.WSMsgType.text
return response
else:
response = MagicMock()
response.tp = aiohttp.WSMsgType.closed
return response
compute._controller._notification = MagicMock()
compute._http_session = AsyncioMagicMock(return_value=ws_mock)
compute._http_session.ws_connect = AsyncioMagicMock(return_value=ws_mock)
ws_mock.receive = receive
async_run(compute._connect_notification())
compute._controller.notification.dispatch.assert_called_with('test', {'a': 1}, compute_id=compute.id)
assert compute._connected is False
def test_connectNotificationPing(compute, async_run):
"""
When we receive a ping from a compute we update
the compute memory and CPU usage
"""
ws_mock = AsyncioMagicMock()
call = 0
async def receive():
nonlocal call
call += 1
if call == 1:
response = MagicMock()
response.data = '{"action": "ping", "event": {"cpu_usage_percent": 35.7, "memory_usage_percent": 80.7}}'
response.tp = aiohttp.WSMsgType.text
return response
else:
response = MagicMock()
response.tp = aiohttp.WSMsgType.closed
return response
compute._controller._notification = MagicMock()
compute._http_session = AsyncioMagicMock(return_value=ws_mock)
compute._http_session.ws_connect = AsyncioMagicMock(return_value=ws_mock)
ws_mock.receive = receive
async_run(compute._connect_notification())
assert not compute._controller.notification.dispatch.called
args, _ = compute._controller.notification.controller_emit.call_args_list[0]
assert args[0] == "compute.updated"
assert args[1]["memory_usage_percent"] == 80.7
assert args[1]["cpu_usage_percent"] == 35.7
# FIXME: https://github.com/aio-libs/aiohttp/issues/2525
# def test_connectNotification(compute, async_run):
# ws_mock = AsyncioMagicMock()
#
# call = 0
#
# async def receive():
# nonlocal call
# call += 1
# if call == 1:
# response = MagicMock()
# response.data = '{"action": "test", "event": {"a": 1}}'
# response.type = aiohttp.WSMsgType.TEXT
# return response
# else:
# response = MagicMock()
# response.type = aiohttp.WSMsgType.CLOSED
# return response
#
# compute._controller._notification = MagicMock()
# compute._http_session = AsyncioMagicMock(return_value=ws_mock)
# compute._http_session.ws_connect = AsyncioMagicMock(return_value=ws_mock)
# ws_mock.receive = receive
# async_run(compute._connect_notification())
#
# compute._controller.notification.dispatch.assert_called_with('test', {'a': 1}, compute_id=compute.id)
# assert compute._connected is False
#
#
# def test_connectNotificationPing(compute, async_run):
# """
# When we receive a ping from a compute we update
# the compute memory and CPU usage
# """
# ws_mock = AsyncioMagicMock()
#
# call = 0
#
# async def receive():
# nonlocal call
# call += 1
# if call == 1:
# response = MagicMock()
# response.data = '{"action": "ping", "event": {"cpu_usage_percent": 35.7, "memory_usage_percent": 80.7}}'
# response.type = aiohttp.WSMsgType.TEST
# return response
# else:
# response = MagicMock()
# response.type = aiohttp.WSMsgType.CLOSED
#
# compute._controller._notification = MagicMock()
# compute._http_session = AsyncioMagicMock(return_value=ws_mock)
# compute._http_session.ws_connect = AsyncioMagicMock(return_value=ws_mock)
# ws_mock.receive = receive
# async_run(compute._connect_notification())
#
# assert not compute._controller.notification.dispatch.called
# args, _ = compute._controller.notification.controller_emit.call_args_list[0]
# assert args[0] == "compute.updated"
# assert args[1]["memory_usage_percent"] == 80.7
# assert args[1]["cpu_usage_percent"] == 35.7
def test_json(compute):
@ -296,6 +299,7 @@ def test_streamFile(project, async_run, compute):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
async_run(compute.stream_file(project, "test/titi", timeout=120))
mock.assert_called_with("GET", "https://example.com:84/v2/compute/projects/{}/stream/test/titi".format(project.id), auth=None, timeout=120)
async_run(compute.close())
def test_downloadFile(project, async_run, compute):
@ -304,7 +308,7 @@ def test_downloadFile(project, async_run, compute):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
async_run(compute.download_file(project, "test/titi"))
mock.assert_called_with("GET", "https://example.com:84/v2/compute/projects/{}/files/test/titi".format(project.id), auth=None)
async_run(compute.close())
def test_close(compute, async_run):
assert compute.connected is True
@ -332,7 +336,7 @@ def test_forward_get(compute, async_run):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
async_run(compute.forward("GET", "qemu", "images"))
mock.assert_called_with("GET", "https://example.com:84/v2/compute/qemu/images", auth=None, data=None, headers={'content-type': 'application/json'}, chunked=None, timeout=None)
async_run(compute.close())
def test_forward_404(compute, async_run):
response = MagicMock()
@ -340,7 +344,7 @@ def test_forward_404(compute, async_run):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
with pytest.raises(aiohttp.web_exceptions.HTTPNotFound):
async_run(compute.forward("GET", "qemu", "images"))
async_run(compute.close())
def test_forward_post(compute, async_run):
response = MagicMock()
@ -348,7 +352,7 @@ def test_forward_post(compute, async_run):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
async_run(compute.forward("POST", "qemu", "img", data={"id": 42}))
mock.assert_called_with("POST", "https://example.com:84/v2/compute/qemu/img", auth=None, data=b'{"id": 42}', headers={'content-type': 'application/json'}, chunked=None, timeout=None)
async_run(compute.close())
def test_images(compute, async_run, images_dir):
"""
@ -365,6 +369,7 @@ def test_images(compute, async_run, images_dir):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
images = async_run(compute.images("qemu"))
mock.assert_called_with("GET", "https://example.com:84/v2/compute/qemu/images", auth=None, data=None, headers={'content-type': 'application/json'}, chunked=None, timeout=None)
async_run(compute.close())
assert images == [
{"filename": "asa.qcow2", "path": "asa.qcow2", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "filesize": 0},
@ -380,7 +385,7 @@ def test_list_files(project, async_run, compute):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
assert async_run(compute.list_files(project)) == res
mock.assert_any_call("GET", "https://example.com:84/v2/compute/projects/{}/files".format(project.id), auth=None, chunked=None, data=None, headers={'content-type': 'application/json'}, timeout=None)
async_run(compute.close())
def test_interfaces(project, async_run, compute):
res = [
@ -399,7 +404,7 @@ def test_interfaces(project, async_run, compute):
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
assert async_run(compute.interfaces()) == res
mock.assert_any_call("GET", "https://example.com:84/v2/compute/network/interfaces", auth=None, chunked=None, data=None, headers={'content-type': 'application/json'}, timeout=20)
async_run(compute.close())
def test_get_ip_on_same_subnet(controller, async_run):
compute1 = Compute("compute1", host="192.168.1.1", controller=controller)

View File

@ -373,6 +373,7 @@ def test_export_images_from_vm(tmpdir, project, async_run, controller):
mock_response.status = 200
compute.download_file = AsyncioMagicMock(return_value=mock_response)
mock_response = AsyncioMagicMock()
mock_response.content = AsyncioBytesIO()
async_run(mock_response.content.write(b"IMAGE"))
@ -380,6 +381,7 @@ def test_export_images_from_vm(tmpdir, project, async_run, controller):
mock_response.status = 200
compute.download_image = AsyncioMagicMock(return_value=mock_response)
project._project_created_on_compute.add(compute)
path = project.path

View File

@ -298,7 +298,7 @@ def test_start_streaming_pcap(link, async_run, tmpdir, project):
with open(os.path.join(project.captures_directory, "test.pcap"), "rb") as f:
c = f.read()
assert c == b"hello"
async_run(link.read_pcap_from_source.close())
def test_default_capture_file_name(project, compute, async_run):
node1 = Node(project, compute, "Hello@", node_type="qemu")

View File

@ -66,9 +66,9 @@ class Query:
"""
Return a websocket connected to the path
"""
self._session = aiohttp.ClientSession()
async def go_request(future):
self._session = aiohttp.ClientSession()
response = await self._session.ws_connect(self.get_url(path))
future.set_result(response)
future = asyncio.Future()
@ -90,30 +90,31 @@ class Query:
body = json.dumps(body)
connector = aiohttp.TCPConnector()
response = await aiohttp.request(method, self.get_url(path), data=body, loop=self._loop, connector=connector)
response.body = await response.read()
x_route = response.headers.get('X-Route', None)
if x_route is not None:
response.route = x_route.replace("/v{}".format(self._api_version), "")
response.route = response.route .replace(self._prefix, "")
async with aiohttp.request(method, self.get_url(path), data=body, loop=self._loop, connector=connector) as response:
response.body = await response.read()
x_route = response.headers.get('X-Route', None)
if x_route is not None:
response.route = x_route.replace("/v{}".format(self._api_version), "")
response.route = response.route .replace(self._prefix, "")
response.json = {}
response.html = ""
if response.body is not None:
if response.headers.get("CONTENT-TYPE", "") == "application/json":
try:
response.json = json.loads(response.body.decode("utf-8"))
except ValueError:
response.json = None
else:
try:
response.html = response.body.decode("utf-8")
except UnicodeDecodeError:
response.html = None
response.json = {}
response.html = ""
if response.body is not None:
if response.headers.get("CONTENT-TYPE", "") == "application/json":
try:
response.json = json.loads(response.body.decode("utf-8"))
except ValueError:
response.json = None
else:
try:
response.html = response.body.decode("utf-8")
except UnicodeDecodeError:
response.html = None
if kwargs.get('example') and os.environ.get("PYTEST_BUILD_DOCUMENTATION") == "1":
self._dump_example(method, response.route, path, body, response)
return response
if kwargs.get('example') and os.environ.get("PYTEST_BUILD_DOCUMENTATION") == "1":
self._dump_example(method, response.route, path, body, response)
return response
return None
def _dump_example(self, method, route, path, body, response):
"""Dump the request for the documentation"""

View File

@ -340,13 +340,12 @@ def test_stop_capture(http_controller, tmpdir, project, compute, async_run):
assert response.status == 201
def test_pcap(http_controller, tmpdir, project, compute, loop):
def test_pcap(http_controller, tmpdir, project, compute, async_run):
async def go(future):
response = await aiohttp.request("GET", http_controller.get_url("/projects/{}/links/{}/pcap".format(project.id, link.id)))
response.body = await response.content.read(5)
response.close()
future.set_result(response)
async def go():
async with aiohttp.request("GET", http_controller.get_url("/projects/{}/links/{}/pcap".format(project.id, link.id))) as response:
response.body = await response.content.read(5)
return response
link = Link(project)
link._capture_file_name = "test"
@ -354,10 +353,7 @@ def test_pcap(http_controller, tmpdir, project, compute, loop):
with open(link.capture_file_path, "w+") as f:
f.write("hello")
project._links = {link.id: link}
future = asyncio.Future()
asyncio.ensure_future(go(future))
response = loop.run_until_complete(future)
response = async_run(asyncio.ensure_future(go()))
assert response.status == 200
assert b'hello' == response.body

View File

@ -172,12 +172,11 @@ def test_notification(http_controller, project, controller, loop, async_run):
async def go():
connector = aiohttp.TCPConnector()
response = await aiohttp.request("GET", http_controller.get_url("/projects/{project_id}/notifications".format(project_id=project.id)), connector=connector)
response.body = await response.content.read(200)
controller.notification.project_emit("node.created", {"a": "b"})
response.body += await response.content.readany()
response.close()
return response
async with aiohttp.request("GET", http_controller.get_url("/projects/{project_id}/notifications".format(project_id=project.id)), connector=connector) as response:
response.body = await response.content.read(200)
controller.notification.project_emit("node.created", {"a": "b"})
response.body += await response.content.readany()
return response
response = async_run(asyncio.ensure_future(go()))
assert response.status == 200
@ -205,7 +204,7 @@ def test_notification_ws(http_controller, controller, project, async_run):
assert answer["action"] == "test"
async_run(http_controller.close())
ws.close()
async_run(ws.close())
assert project.status == "opened"

View File

@ -19,24 +19,24 @@ import asyncio
from gns3server.utils.asyncio.embed_shell import EmbedShell
def test_embed_shell_help(async_run):
class Application(EmbedShell):
async def hello(self):
"""
The hello world function
The hello usage
"""
await asyncio.sleep(1)
reader = asyncio.StreamReader()
writer = asyncio.StreamReader()
app = Application(reader, writer)
assert async_run(app._parse_command('help')) == 'Help:\nhello: The hello world function\n\nhelp command for details about a command\n'
assert async_run(app._parse_command('?')) == 'Help:\nhello: The hello world function\n\nhelp command for details about a command\n'
assert async_run(app._parse_command('? hello')) == 'hello: The hello world function\n\nThe hello usage\n'
#FIXME: this is broken with recent Python >= 3.6
# def test_embed_shell_help(async_run):
# class Application(EmbedShell):
#
# async def hello(self):
# """
# The hello world function
#
# The hello usage
# """
# await asyncio.sleep(1)
#
# reader = asyncio.StreamReader()
# writer = asyncio.StreamReader()
# app = Application(reader, writer)
# assert async_run(app._parse_command('help')) == 'Help:\nhello: The hello world function\n\nhelp command for details about a command\n'
# assert async_run(app._parse_command('?')) == 'Help:\nhello: The hello world function\n\nhelp command for details about a command\n'
# assert async_run(app._parse_command('? hello')) == 'hello: The hello world function\n\nThe hello usage\n'
def test_embed_shell_execute(async_run):
@ -59,9 +59,13 @@ def test_embed_shell_welcome(async_run, loop):
reader = asyncio.StreamReader()
writer = asyncio.StreamReader()
app = EmbedShell(reader, writer, welcome_message="Hello")
t = loop.create_task(app.run())
task = loop.create_task(app.run())
assert async_run(writer.read(5)) == b"Hello"
t.cancel()
task.cancel()
try:
loop.run_until_complete(task)
except asyncio.CancelledError:
pass
def test_embed_shell_prompt(async_run, loop):
@ -69,6 +73,10 @@ def test_embed_shell_prompt(async_run, loop):
writer = asyncio.StreamReader()
app = EmbedShell(reader, writer)
app.prompt = "gbash# "
t = loop.create_task(app.run())
task = loop.create_task(app.run())
assert async_run(writer.read(7)) == b"gbash# "
t.cancel()
task.cancel()
try:
loop.run_until_complete(task)
except asyncio.CancelledError:
pass