diff --git a/.travis.yml b/.travis.yml
index e4f308b5..940ad1db 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,3 +30,4 @@ env:
- PYTHON_VERSION=3.4
- PYTHON_VERSION=3.5
- PYTHON_VERSION=3.6
+ - PYTHON_VERSION=3.7
diff --git a/CHANGELOG b/CHANGELOG
index 46c1f91a..cd56eb79 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,13 @@
# Change Log
+## 2.1.9 13/08/2018
+
+* Fix some more problems with interface short names. Fixes https://github.com/GNS3/gns3-gui/issues/2562
+* Fix incorrect short port names in topology summary. Fixes https://github.com/GNS3/gns3-gui/issues/2562
+* Set lower process priority when computing idle-pc value on Windows. Ref #2522.
+* Catch exception: ZIP does not support timestamps before 1980. Ref #1360.
+* Sync appliances
+
## 2.1.8 14/06/2018
* 'caplog.text()' syntax is deprecated, use 'caplog.text' property instead.
diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py
index e7a95a26..859e58cd 100644
--- a/gns3server/compute/base_node.py
+++ b/gns3server/compute/base_node.py
@@ -29,7 +29,7 @@ import re
from gns3server.utils.interfaces import interfaces
from ..compute.port_manager import PortManager
-from ..utils.asyncio import wait_run_in_executor, locked_coroutine
+from ..utils.asyncio import wait_run_in_executor, locking
from ..utils.asyncio.telnet_server import AsyncioTelnetServer
from ..ubridge.hypervisor import Hypervisor
from ..ubridge.ubridge_error import UbridgeError
@@ -547,7 +547,8 @@ class BaseNode:
except UbridgeError as e:
raise UbridgeError("Error while sending command '{}': {}: {}".format(command, e, self._ubridge_hypervisor.read_stdout()))
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def _start_ubridge(self):
"""
Starts uBridge (handles connections to and from this node).
diff --git a/gns3server/compute/docker/__init__.py b/gns3server/compute/docker/__init__.py
index 8cccf254..53948a52 100644
--- a/gns3server/compute/docker/__init__.py
+++ b/gns3server/compute/docker/__init__.py
@@ -25,7 +25,7 @@ import asyncio
import logging
import aiohttp
from gns3server.utils import parse_version
-from gns3server.utils.asyncio import locked_coroutine
+from gns3server.utils.asyncio import locking
from gns3server.compute.base_manager import BaseManager
from gns3server.compute.docker.docker_vm import DockerVM
from gns3server.compute.docker.docker_error import DockerError, DockerHttp304Error, DockerHttp404Error
@@ -187,7 +187,8 @@ class Docker(BaseManager):
autoping=True)
return connection
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def pull_image(self, image, progress_callback=None):
"""
Pulls an image from the Docker repository
diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py
index daf88fab..b03e1329 100644
--- a/gns3server/compute/docker/docker_vm.py
+++ b/gns3server/compute/docker/docker_vm.py
@@ -28,7 +28,8 @@ import os
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio.raw_command_server import AsyncioRawCommandServer
-from gns3server.utils.asyncio import wait_for_file_creation, asyncio_ensure_future
+from gns3server.utils.asyncio import wait_for_file_creation
+from gns3server.utils.asyncio import asyncio_ensure_future
from gns3server.utils.get_resource import get_resource
from gns3server.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
diff --git a/gns3server/compute/dynamips/__init__.py b/gns3server/compute/dynamips/__init__.py
index 6c8f416b..140c2af8 100644
--- a/gns3server/compute/dynamips/__init__.py
+++ b/gns3server/compute/dynamips/__init__.py
@@ -36,6 +36,7 @@ log = logging.getLogger(__name__)
from gns3server.utils.interfaces import interfaces, is_interface_up
from gns3server.utils.asyncio import wait_run_in_executor, asyncio_ensure_future
from gns3server.utils import parse_version
+from gns3server.utils.asyncio import asyncio_ensure_future
from uuid import uuid4
from ..base_manager import BaseManager
from ..port_manager import PortManager
diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py
index f396be87..f74f0aa8 100644
--- a/gns3server/compute/iou/iou_vm.py
+++ b/gns3server/compute/iou/iou_vm.py
@@ -43,7 +43,7 @@ from .utils.iou_export import nvram_export
from gns3server.ubridge.ubridge_error import UbridgeError
from gns3server.utils.file_watcher import FileWatcher
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
-from gns3server.utils.asyncio import locked_coroutine
+from gns3server.utils.asyncio import locking
import gns3server.utils.asyncio
import gns3server.utils.images
@@ -552,7 +552,8 @@ class IOUVM(BaseNode):
# configure networking support
yield from self._networking()
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def _networking(self):
"""
Configures the IOL bridge in uBridge.
diff --git a/gns3server/compute/virtualbox/virtualbox_vm.py b/gns3server/compute/virtualbox/virtualbox_vm.py
index 32645339..5a1038e0 100644
--- a/gns3server/compute/virtualbox/virtualbox_vm.py
+++ b/gns3server/compute/virtualbox/virtualbox_vm.py
@@ -33,7 +33,7 @@ import xml.etree.ElementTree as ET
from gns3server.utils import parse_version
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio.serial import asyncio_open_serial
-from gns3server.utils.asyncio import locked_coroutine
+from gns3server.utils.asyncio import locking
from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
from gns3server.compute.nios.nio_udp import NIOUDP
from gns3server.compute.adapters.ethernet_adapter import EthernetAdapter
@@ -296,7 +296,8 @@ class VirtualBoxVM(BaseNode):
if (yield from self.check_hw_virtualization()):
self._hw_virtualization = True
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def stop(self):
"""
Stops this VirtualBox VM.
diff --git a/gns3server/compute/vmware/__init__.py b/gns3server/compute/vmware/__init__.py
index d41a48be..574826f4 100644
--- a/gns3server/compute/vmware/__init__.py
+++ b/gns3server/compute/vmware/__init__.py
@@ -32,6 +32,7 @@ import shlex
from collections import OrderedDict
from gns3server.utils.interfaces import interfaces
from gns3server.utils.asyncio import subprocess_check_output
+from gns3server.utils.asyncio import asyncio_ensure_future
from gns3server.utils import parse_version
log = logging.getLogger(__name__)
diff --git a/gns3server/compute/vmware/vmware_vm.py b/gns3server/compute/vmware/vmware_vm.py
index 69b85816..f4976678 100644
--- a/gns3server/compute/vmware/vmware_vm.py
+++ b/gns3server/compute/vmware/vmware_vm.py
@@ -26,7 +26,7 @@ import tempfile
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio.serial import asyncio_open_serial
-from gns3server.utils.asyncio import locked_coroutine
+from gns3server.utils.asyncio import locking
from collections import OrderedDict
from .vmware_error import VMwareError
from ..nios.nio_udp import NIOUDP
@@ -94,7 +94,8 @@ class VMwareVM(BaseNode):
return self._vmnets
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def _control_vm(self, subcommand, *additional_args):
args = [self._vmx_path]
diff --git a/gns3server/controller/compute.py b/gns3server/controller/compute.py
index 3c2ad23e..319093f8 100644
--- a/gns3server/controller/compute.py
+++ b/gns3server/controller/compute.py
@@ -27,9 +27,9 @@ from operator import itemgetter
from ..utils import parse_version
from ..utils.images import list_images
-from ..utils.asyncio import locked_coroutine, asyncio_ensure_future
+from ..utils.asyncio import locking, asyncio_ensure_future
from ..controller.controller_error import ControllerError
-from ..version import __version__
+from ..version import __version__, __version_info__
import logging
@@ -95,6 +95,7 @@ class Compute:
self._set_auth(user, password)
self._cpu_usage_percent = None
self._memory_usage_percent = None
+ self._last_error = None
self._capabilities = {
"version": None,
"node_types": []
@@ -137,6 +138,14 @@ class Compute:
self._password = None
self._auth = aiohttp.BasicAuth(self._user, "")
+ def set_last_error(self, msg):
+ """
+ Set the last error message for this compute.
+
+ :param msg: message
+ """
+ self._last_error = msg
+
@asyncio.coroutine
def interfaces(self):
"""
@@ -301,7 +310,8 @@ class Compute:
"connected": self._connected,
"cpu_usage_percent": self._cpu_usage_percent,
"memory_usage_percent": self._memory_usage_percent,
- "capabilities": self._capabilities
+ "capabilities": self._capabilities,
+ "last_error": self._last_error
}
@asyncio.coroutine
@@ -398,7 +408,8 @@ class Compute:
except aiohttp.web.HTTPConflict:
pass
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def connect(self):
"""
Check if remote server is accessible
@@ -420,7 +431,7 @@ class Compute:
if self._connection_failure == 10:
log.error("Could not connect to compute '{}' after multiple attempts: {}".format(self._id, e))
yield from self._controller.close_compute_projects(self)
- asyncio.get_event_loop().call_later(2, lambda: asyncio_ensure_future(self._try_reconnect()))
+ asyncio.get_event_loop().call_later(2, lambda: asyncio.async(self._try_reconnect()))
return
except aiohttp.web.HTTPNotFound:
raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server or it's a 1.X server".format(self._id))
@@ -432,16 +443,36 @@ class Compute:
raise aiohttp.web.HTTPConflict(text="Invalid server url for server {}".format(self._id))
if "version" not in response.json:
+ msg = "The server {} is not a GNS3 server".format(self._id)
+ log.error(msg)
self._http_session.close()
- raise aiohttp.web.HTTPConflict(text="The server {} is not a GNS3 server".format(self._id))
+ raise aiohttp.web.HTTPConflict(text=msg)
self._capabilities = response.json
- if parse_version(__version__)[:2] != parse_version(response.json["version"])[:2]:
- self._http_session.close()
- raise aiohttp.web.HTTPConflict(text="The server {} versions are not compatible {} != {}".format(self._id, __version__, response.json["version"]))
+
+ if response.json["version"].split("-")[0] != __version__.split("-")[0]:
+ msg = "GNS3 controller version {} is not the same as compute server {} version {}".format(__version__,
+ self._name,
+ response.json["version"])
+ if __version_info__[3] == 0:
+ # Stable release
+ log.error(msg)
+ 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()
+ self._last_error = msg
+ raise aiohttp.web.HTTPConflict(text=msg)
+ else:
+ msg = "{}\nUsing different versions may result in unexpected problems. Please use at your own risk.".format(msg)
+ self._controller.notification.emit("log.warning", {"message": msg})
self._notifications = asyncio.gather(self._connect_notification())
self._connected = True
self._connection_failure = 0
+ self._last_error = None
self._controller.notification.controller_emit("compute.updated", self.__json__())
@asyncio.coroutine
diff --git a/gns3server/controller/export_project.py b/gns3server/controller/export_project.py
index 326a0e31..c8725a5e 100644
--- a/gns3server/controller/export_project.py
+++ b/gns3server/controller/export_project.py
@@ -16,6 +16,7 @@
# along with this program. If not, see .
import os
+import sys
import json
import asyncio
import aiohttp
@@ -23,6 +24,7 @@ import zipfile
import tempfile
import zipstream
+from datetime import datetime
import logging
log = logging.getLogger(__name__)
@@ -77,6 +79,7 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id
# ignore the .gns3 file
if file.endswith(".gns3"):
continue
+ _patch_mtime(path)
zstream.write(path, os.path.relpath(path, project._path), compress_type=zipfile.ZIP_DEFLATED)
# Export files from remote computes
@@ -99,12 +102,29 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id
f.write(data)
response.close()
f.close()
+ _patch_mtime(temp_path)
zstream.write(temp_path, arcname=compute_file["path"], compress_type=zipfile.ZIP_DEFLATED)
downloaded_files.add(compute_file['path'])
return zstream
+def _patch_mtime(path):
+ """
+ Patch the file mtime because ZIP does not support timestamps before 1980
+
+ :param path: file path
+ """
+
+ if sys.platform.startswith("win"):
+ # only UNIX type platforms
+ return
+ st = os.stat(path)
+ file_date = datetime.fromtimestamp(st.st_mtime)
+ if file_date.year < 1980:
+ new_mtime = file_date.replace(year=1980).timestamp()
+ os.utime(path, (st.st_atime, new_mtime))
+
def _is_exportable(path):
"""
:returns: True if file should not be included in the final archive
@@ -228,6 +248,7 @@ def _export_local_image(image, zstream):
if os.path.exists(path):
arcname = os.path.join("images", directory, os.path.basename(image))
+ _patch_mtime(path)
zstream.write(path, arcname)
return
diff --git a/gns3server/controller/gns3vm/__init__.py b/gns3server/controller/gns3vm/__init__.py
index 99567cfe..44fcf950 100644
--- a/gns3server/controller/gns3vm/__init__.py
+++ b/gns3server/controller/gns3vm/__init__.py
@@ -21,7 +21,7 @@ import asyncio
import aiohttp
import ipaddress
-from ...utils.asyncio import locked_coroutine, asyncio_ensure_future
+from ...utils.asyncio import locking, asyncio_ensure_future
from .vmware_gns3_vm import VMwareGNS3VM
from .virtualbox_gns3_vm import VirtualBoxGNS3VM
from .hyperv_gns3_vm import HyperVGNS3VM
@@ -278,13 +278,15 @@ class GNS3VM:
except GNS3VMError as e:
# User will receive the error later when they will try to use the node
try:
- yield from self._controller.add_compute(compute_id="vm",
- name="GNS3 VM ({})".format(self.current_engine().vmname),
- host=None,
- force=True)
+ compute = yield from self._controller.add_compute(compute_id="vm",
+ name="GNS3 VM ({})".format(self.current_engine().vmname),
+ host=None,
+ force=True)
+ compute.set_last_error(str(e))
+
except aiohttp.web.HTTPConflict:
pass
- log.error("Can't start the GNS3 VM: %s", str(e))
+ log.error("Cannot start the GNS3 VM: {}".format(e))
@asyncio.coroutine
def exit_vm(self):
@@ -298,7 +300,8 @@ class GNS3VM:
except GNS3VMError as e:
log.warning(str(e))
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def start(self):
"""
Start the GNS3 VM
@@ -323,8 +326,9 @@ class GNS3VM:
yield from engine.start()
except Exception as e:
yield from self._controller.delete_compute("vm")
- log.error("Can't start the GNS3 VM: {}".format(str(e)))
+ log.error("Cannot start the GNS3 VM: {}".format(str(e)))
yield from compute.update(name="GNS3 VM ({})".format(engine.vmname))
+ compute.set_last_error(str(e))
raise e
yield from compute.connect() # we can connect now that the VM has started
yield from compute.update(name="GNS3 VM ({})".format(engine.vmname),
@@ -370,8 +374,11 @@ class GNS3VM:
self._controller.notification.controller_emit("log.warning", {"message": msg})
except ComputeError as e:
log.warning("Could not check the VM is in the same subnet as the local server: {}".format(e))
+ except aiohttp.web.HTTPConflict as e:
+ log.warning("Could not check the VM is in the same subnet as the local server: {}".format(e.text))
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def _suspend(self):
"""
Suspend the GNS3 VM
@@ -383,7 +390,8 @@ class GNS3VM:
log.info("Suspend the GNS3 VM")
yield from engine.suspend()
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def _stop(self):
"""
Stop the GNS3 VM
diff --git a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py
index f491e32f..ef1fba52 100644
--- a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py
+++ b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import sys
import aiohttp
import logging
import asyncio
@@ -107,7 +108,6 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
Check if the DHCP server associated with a vboxnet is enabled.
:param vboxnet: vboxnet name
-
:returns: boolean
"""
@@ -125,6 +125,41 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
return True
return False
+ @asyncio.coroutine
+ def _check_vboxnet_exists(self, vboxnet):
+ """
+ Check if the vboxnet interface exists
+
+ :param vboxnet: vboxnet name
+ :returns: boolean
+ """
+
+ properties = yield from self._execute("list", ["hostonlyifs"])
+ for prop in properties.splitlines():
+ try:
+ name, value = prop.split(':', 1)
+ except ValueError:
+ continue
+ if name.strip() == "Name" and value.strip() == vboxnet:
+ return True
+ return False
+
+ @asyncio.coroutine
+ def _find_first_available_vboxnet(self):
+ """
+ Find the first available vboxnet.
+ """
+
+ properties = yield from self._execute("list", ["hostonlyifs"])
+ for prop in properties.splitlines():
+ try:
+ name, value = prop.split(':', 1)
+ except ValueError:
+ continue
+ if name.strip() == "Name":
+ return value.strip()
+ return None
+
@asyncio.coroutine
def _check_vbox_port_forwarding(self):
"""
@@ -158,18 +193,32 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
# get a NAT interface number
nat_interface_number = yield from self._look_for_interface("nat")
if nat_interface_number < 0:
- raise GNS3VMError("The GNS3 VM: {} must have a NAT interface configured in order to start".format(self.vmname))
+ raise GNS3VMError('VM "{}" must have a NAT interface configured in order to start'.format(self.vmname))
hostonly_interface_number = yield from self._look_for_interface("hostonly")
if hostonly_interface_number < 0:
- raise GNS3VMError("The GNS3 VM: {} must have a host only interface configured in order to start".format(self.vmname))
+ raise GNS3VMError('VM "{}" must have a host-only interface configured in order to start'.format(self.vmname))
vboxnet = yield from self._look_for_vboxnet(hostonly_interface_number)
if vboxnet is None:
- raise GNS3VMError("VirtualBox host-only network could not be found for interface {} on GNS3 VM".format(hostonly_interface_number))
+ raise GNS3VMError('A VirtualBox host-only network could not be found on network adapter {} for "{}"'.format(hostonly_interface_number, self._vmname))
+
+ if not (yield from self._check_vboxnet_exists(vboxnet)):
+ if sys.platform.startswith("win") and vboxnet == "vboxnet0":
+ # The GNS3 VM is configured with vboxnet0 by default which is not available
+ # on Windows. Try to patch this with the first available vboxnet we find.
+ first_available_vboxnet = yield from self._find_first_available_vboxnet()
+ if first_available_vboxnet is None:
+ raise GNS3VMError('Please add a VirtualBox host-only network with DHCP enabled and attached it to network adapter {} for "{}"'.format(hostonly_interface_number, self._vmname))
+ yield from self.set_hostonly_network(hostonly_interface_number, first_available_vboxnet)
+ vboxnet = first_available_vboxnet
+ else:
+ raise GNS3VMError('VirtualBox host-only network "{}" does not exist, please make the sure the network adapter {} configuration is valid for "{}"'.format(vboxnet,
+ hostonly_interface_number,
+ self._vmname))
if not (yield from self._check_dhcp_server(vboxnet)):
- raise GNS3VMError("DHCP must be enabled on VirtualBox host-only network: {} for GNS3 VM".format(vboxnet))
+ raise GNS3VMError('DHCP must be enabled on VirtualBox host-only network "{}"'.format(vboxnet))
vm_state = yield from self._get_state()
log.info('"{}" state is {}'.format(self._vmname, vm_state))
@@ -311,3 +360,17 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
yield from self._execute("modifyvm", [self._vmname, "--memory", str(ram)], timeout=3)
log.info("GNS3 VM RAM amount set to {}".format(ram))
+
+ @asyncio.coroutine
+ def set_hostonly_network(self, adapter_number, hostonly_network_name):
+ """
+ Set a VirtualBox host-only network on a network adapter for the GNS3 VM.
+
+ :param adapter_number: network adapter number
+ :param hostonly_network_name: name of the VirtualBox host-only network
+ """
+
+ yield from self._execute("modifyvm", [self._vmname, "--hostonlyadapter{}".format(adapter_number), hostonly_network_name], timeout=3)
+ log.info('VirtualBox host-only network "{}" set on network adapter {} for "{}"'.format(hostonly_network_name,
+ adapter_number,
+ self._vmname))
diff --git a/gns3server/controller/ports/atm_port.py b/gns3server/controller/ports/atm_port.py
index 51da8d86..f63b9e4b 100644
--- a/gns3server/controller/ports/atm_port.py
+++ b/gns3server/controller/ports/atm_port.py
@@ -33,8 +33,8 @@ class ATMPort(SerialPort):
"""
return "ATM"
- @property
- def short_name_type(self):
+ @staticmethod
+ def short_name_type():
"""
Returns the short name type for this port.
@@ -42,10 +42,6 @@ class ATMPort(SerialPort):
"""
return "a"
- @property
- def short_name(self):
- return "{}".format(self._port_number)
-
@property
def data_link_types(self):
"""
diff --git a/gns3server/controller/ports/ethernet_port.py b/gns3server/controller/ports/ethernet_port.py
index 6847998b..ae3f7e73 100644
--- a/gns3server/controller/ports/ethernet_port.py
+++ b/gns3server/controller/ports/ethernet_port.py
@@ -39,8 +39,8 @@ class EthernetPort(Port):
return "Ethernet"
- @property
- def short_name_type(self):
+ @staticmethod
+ def short_name_type():
"""
Returns the short name type for this port.
diff --git a/gns3server/controller/ports/fastethernet_port.py b/gns3server/controller/ports/fastethernet_port.py
index a8f98780..2a01e14a 100644
--- a/gns3server/controller/ports/fastethernet_port.py
+++ b/gns3server/controller/ports/fastethernet_port.py
@@ -34,8 +34,8 @@ class FastEthernetPort(Port):
return "FastEthernet"
- @property
- def short_name_type(self):
+ @staticmethod
+ def short_name_type():
"""
Returns the short name type for this port.
diff --git a/gns3server/controller/ports/frame_relay_port.py b/gns3server/controller/ports/frame_relay_port.py
index 356c13bd..87049917 100644
--- a/gns3server/controller/ports/frame_relay_port.py
+++ b/gns3server/controller/ports/frame_relay_port.py
@@ -34,10 +34,6 @@ class FrameRelayPort(SerialPort):
return "FrameRelay"
- @property
- def short_name(self):
- return "{}".format(self._port_number)
-
@property
def data_link_types(self):
"""
diff --git a/gns3server/controller/ports/gigabitethernet_port.py b/gns3server/controller/ports/gigabitethernet_port.py
index c96b820f..bcf7b143 100644
--- a/gns3server/controller/ports/gigabitethernet_port.py
+++ b/gns3server/controller/ports/gigabitethernet_port.py
@@ -34,8 +34,8 @@ class GigabitEthernetPort(Port):
return "GigabitEthernet"
- @property
- def short_name_type(self):
+ @staticmethod
+ def short_name_type():
"""
Returns the short name type for this port.
diff --git a/gns3server/controller/ports/port.py b/gns3server/controller/ports/port.py
index 4fc32720..601e8024 100644
--- a/gns3server/controller/ports/port.py
+++ b/gns3server/controller/ports/port.py
@@ -85,9 +85,9 @@ class Port:
if self._short_name:
return self._short_name
elif '/' in self._name:
- return self._name.replace(self.long_name_type(), self.short_name_type)
+ return self._name.replace(self.long_name_type(), self.short_name_type())
elif self._name.startswith("{}{}".format(self.long_name_type(), self._interface_number)):
- return self.short_name_type + "{}".format(self._interface_number)
+ return self.short_name_type() + "{}".format(self._interface_number)
return self._name
@short_name.setter
diff --git a/gns3server/controller/ports/port_factory.py b/gns3server/controller/ports/port_factory.py
index 533676af..4cf06d11 100644
--- a/gns3server/controller/ports/port_factory.py
+++ b/gns3server/controller/ports/port_factory.py
@@ -209,7 +209,7 @@ class DynamipsPortFactory:
for port_number in range(0, cls.ADAPTER_MATRIX[properties[name]]["nb_ports"]):
name = "{}{}/{}".format(port_class.long_name_type(), adapter_number, port_number)
port = port_class(name, adapter_number, adapter_number, port_number)
- port.short_name = "{}{}/{}".format(port.short_name_type, adapter_number, port_number)
+ port.short_name = "{}{}/{}".format(port_class.short_name_type(), adapter_number, port_number)
ports.append(port)
adapter_number += 1
elif name.startswith("wic") and properties[name]:
@@ -218,7 +218,7 @@ class DynamipsPortFactory:
for port_number in range(0, cls.WIC_MATRIX[properties[name]]["nb_ports"]):
name = "{}{}/{}".format(port_class.long_name_type(), 0, display_wic_port_number)
port = port_class(name, 0, 0, wic_port_number)
- port.short_name = "{}{}/{}".format(port.short_name_type, 0, display_wic_port_number)
+ port.short_name = "{}{}/{}".format(port_class.short_name_type(), 0, display_wic_port_number)
ports.append(port)
display_wic_port_number += 1
wic_port_number += 1
diff --git a/gns3server/controller/ports/pos_port.py b/gns3server/controller/ports/pos_port.py
index 152e1f62..bd6a508e 100644
--- a/gns3server/controller/ports/pos_port.py
+++ b/gns3server/controller/ports/pos_port.py
@@ -33,8 +33,8 @@ class POSPort(SerialPort):
"""
return "POS"
- @property
- def short_name_type(self):
+ @staticmethod
+ def short_name_type():
"""
Returns the short name type for this port.
diff --git a/gns3server/controller/ports/serial_port.py b/gns3server/controller/ports/serial_port.py
index 090f3a47..37fb4ebc 100644
--- a/gns3server/controller/ports/serial_port.py
+++ b/gns3server/controller/ports/serial_port.py
@@ -34,8 +34,8 @@ class SerialPort(Port):
return "Serial"
- @property
- def short_name_type(self):
+ @staticmethod
+ def short_name_type():
"""
Returns the short name type for this port.
diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py
index 02d864d5..452bf8da 100644
--- a/gns3server/controller/project.py
+++ b/gns3server/controller/project.py
@@ -36,8 +36,9 @@ from .udp_link import UDPLink
from ..config import Config
from ..utils.path import check_path_allowed, get_default_project_directory
from ..utils.asyncio.pool import Pool
-from ..utils.asyncio import locked_coroutine, asyncio_ensure_future
+from ..utils.asyncio import locking
from ..utils.asyncio import wait_run_in_executor
+from ..utils.asyncio import asyncio_ensure_future
from .export_project import export_project
from .import_project import import_project
@@ -524,7 +525,8 @@ class Project:
self.dump()
return node
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def __delete_node_links(self, node):
"""
Delete all link connected to this node.
@@ -814,7 +816,8 @@ class Project:
def _topology_file(self):
return os.path.join(self.path, self._filename)
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def open(self):
"""
Load topology elements
diff --git a/gns3server/controller/snapshot.py b/gns3server/controller/snapshot.py
index 8ea0cb26..512e23f5 100644
--- a/gns3server/controller/snapshot.py
+++ b/gns3server/controller/snapshot.py
@@ -101,7 +101,7 @@ class Snapshot:
with tempfile.TemporaryDirectory() as tmpdir:
zipstream = yield from export_project(self._project, tmpdir, keep_compute_id=True, allow_all_nodes=True)
yield from wait_run_in_executor(self._create_snapshot_file, zipstream)
- except OSError as e:
+ except (ValueError, OSError, RuntimeError) as e:
raise aiohttp.web.HTTPConflict(text="Could not create snapshot file '{}': {}".format(self.path, e))
@asyncio.coroutine
diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py
index 14a5ed0f..93124e9e 100644
--- a/gns3server/crash_report.py
+++ b/gns3server/crash_report.py
@@ -57,7 +57,7 @@ class CrashReport:
Report crash to a third party service
"""
- DSN = "sync+https://95d9ad01f98746c2b9dacb7399526440:1e2d320de7be49ebbdebf47caf5b47ff@sentry.io/38482"
+ DSN = "sync+https://56af21e241ed4c1894ebe17bf06b1cd1:6075f91067954267b51e90b9638a6fad@sentry.io/38482"
if hasattr(sys, "frozen"):
cacert = get_resource("cacert.pem")
if cacert is not None and os.path.isfile(cacert):
diff --git a/gns3server/handlers/api/controller/project_handler.py b/gns3server/handlers/api/controller/project_handler.py
index a9e6525f..5f1e7b00 100644
--- a/gns3server/handlers/api/controller/project_handler.py
+++ b/gns3server/handlers/api/controller/project_handler.py
@@ -16,6 +16,7 @@
# along with this program. If not, see .
import os
+import sys
import aiohttp
import asyncio
import tempfile
@@ -27,6 +28,7 @@ from gns3server.controller.export_project import export_project
from gns3server.config import Config
from gns3server.utils.asyncio import asyncio_ensure_future
+
from gns3server.schemas.project import (
PROJECT_OBJECT_SCHEMA,
PROJECT_UPDATE_SCHEMA,
@@ -317,8 +319,8 @@ class ProjectHandler:
yield from response.write_eof()
# 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 (OSError, RuntimeError) as e:
- raise aiohttp.web.HTTPNotFound(text="Can't export project: {}".format(str(e)))
+ except (ValueError, OSError, RuntimeError) as e:
+ raise aiohttp.web.HTTPNotFound(text="Cannot export project: {}".format(str(e)))
@Route.post(
r"/projects/{project_id}/import",
@@ -347,14 +349,25 @@ class ProjectHandler:
# We write the content to a temporary location and after we extract it all.
# It could be more optimal to stream this but it is not implemented in Python.
# Spooled means the file is temporary kept in memory until max_size is reached
+ # Cannot use tempfile.SpooledTemporaryFile(max_size=10000) in Python 3.7 due
+ # to a bug https://bugs.python.org/issue26175
try:
- with tempfile.SpooledTemporaryFile(max_size=10000) as temp:
- while True:
- chunk = yield from request.content.read(1024)
- if not chunk:
- break
- temp.write(chunk)
- project = yield from import_project(controller, request.match_info["project_id"], temp, location=path, name=name)
+ if sys.version_info >= (3, 7) and sys.version_info < (3, 8):
+ with tempfile.TemporaryFile() as temp:
+ while True:
+ chunk = yield from request.content.read(1024)
+ if not chunk:
+ break
+ temp.write(chunk)
+ project = yield from import_project(controller, request.match_info["project_id"], temp, location=path, name=name)
+ else:
+ with tempfile.SpooledTemporaryFile(max_size=10000) as temp:
+ while True:
+ chunk = yield from request.content.read(1024)
+ if not chunk:
+ break
+ temp.write(chunk)
+ project = yield from import_project(controller, request.match_info["project_id"], temp, location=path, name=name)
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not import the project: {}".format(e))
diff --git a/gns3server/handlers/api/controller/server_handler.py b/gns3server/handlers/api/controller/server_handler.py
index 5bc6d95c..62358c73 100644
--- a/gns3server/handlers/api/controller/server_handler.py
+++ b/gns3server/handlers/api/controller/server_handler.py
@@ -72,7 +72,10 @@ class ServerHandler:
# then shutdown the server itself
from gns3server.web.web_server import WebServer
server = WebServer.instance()
- asyncio_ensure_future(server.shutdown_server())
+ try:
+ asyncio_ensure_future(server.shutdown_server())
+ except asyncio.CancelledError:
+ pass
response.set_status(201)
@Route.get(
@@ -127,6 +130,7 @@ class ServerHandler:
return
try:
controller.settings = request.json
+ #controller.save()
except (OSError, PermissionError) as e:
raise HTTPConflict(text="Can't save the settings {}".format(str(e)))
response.json(controller.settings)
diff --git a/gns3server/schemas/compute.py b/gns3server/schemas/compute.py
index 2e8d08bc..c1ea3362 100644
--- a/gns3server/schemas/compute.py
+++ b/gns3server/schemas/compute.py
@@ -104,6 +104,10 @@ COMPUTE_OBJECT_SCHEMA = {
"maximum": 100,
"minimum": 0
},
+ "last_error": {
+ "description": "Last error on the compute",
+ "type": ["string", "null"]
+ },
"capabilities": CAPABILITIES_SCHEMA
},
"additionalProperties": False,
diff --git a/gns3server/schemas/qemu.py b/gns3server/schemas/qemu.py
index 8da99160..23a6bad7 100644
--- a/gns3server/schemas/qemu.py
+++ b/gns3server/schemas/qemu.py
@@ -133,7 +133,7 @@ QEMU_CREATE_SCHEMA = {
},
"boot_priority": {
"description": "QEMU boot priority",
- "enum": ["c", "d", "n", "cn", "cd"]
+ "enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"]
},
"ram": {
"description": "Amount of RAM in MB",
@@ -319,7 +319,7 @@ QEMU_UPDATE_SCHEMA = {
},
"boot_priority": {
"description": "QEMU boot priority",
- "enum": ["c", "d", "n", "cn", "cd"]
+ "enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"]
},
"ram": {
"description": "Amount of RAM in MB",
@@ -504,7 +504,7 @@ QEMU_OBJECT_SCHEMA = {
},
"boot_priority": {
"description": "QEMU boot priority",
- "enum": ["c", "d", "n", "cn", "cd"]
+ "enum": ["c", "d", "n", "cn", "cd", "dn", "dc", "nc", "nd"]
},
"node_directory": {
"description": "Path to the VM working directory",
diff --git a/gns3server/ubridge/ubridge_hypervisor.py b/gns3server/ubridge/ubridge_hypervisor.py
index b32e2233..026045c4 100644
--- a/gns3server/ubridge/ubridge_hypervisor.py
+++ b/gns3server/ubridge/ubridge_hypervisor.py
@@ -20,7 +20,7 @@ import time
import logging
import asyncio
-from ..utils.asyncio import locked_coroutine
+from ..utils.asyncio import locking
from .ubridge_error import UbridgeError
log = logging.getLogger(__name__)
@@ -176,7 +176,8 @@ class UBridgeHypervisor:
self._host = host
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def send(self, command):
"""
Sends commands to this hypervisor.
diff --git a/gns3server/utils/asyncio/__init__.py b/gns3server/utils/asyncio/__init__.py
index 78c84a90..7ed4528d 100644
--- a/gns3server/utils/asyncio/__init__.py
+++ b/gns3server/utils/asyncio/__init__.py
@@ -160,32 +160,32 @@ def wait_for_named_pipe_creation(pipe_path, timeout=60):
return
raise asyncio.TimeoutError()
+#FIXME: Use the following wrapper when we drop Python 3.4 and use the async def syntax
+# def locking(f):
+#
+# @wraps(f)
+# async def wrapper(oself, *args, **kwargs):
+# lock_name = "__" + f.__name__ + "_lock"
+# if not hasattr(oself, lock_name):
+# setattr(oself, lock_name, asyncio.Lock())
+# async with getattr(oself, lock_name):
+# return await f(oself, *args, **kwargs)
+# return wrapper
-def locked_coroutine(f):
- """
- Method decorator that replace asyncio.coroutine that guarantee
- that this specific method of this class instance will not be
- executed twice at the same time
- """
- @asyncio.coroutine
- def new_function(*args, **kwargs):
+def locking(f):
- # In the instance of the class we will store
- # a lock has an attribute.
- lock_var_name = "__" + f.__name__ + "_lock"
- if not hasattr(args[0], lock_var_name):
- setattr(args[0], lock_var_name, asyncio.Lock())
+ @functools.wraps(f)
+ def wrapper(oself, *args, **kwargs):
+ lock_name = "__" + f.__name__ + "_lock"
+ if not hasattr(oself, lock_name):
+ setattr(oself, lock_name, asyncio.Lock())
+ with (yield from getattr(oself, lock_name)):
+ return (yield from f(oself, *args, **kwargs))
+ return wrapper
- with (yield from getattr(args[0], lock_var_name)):
- return (yield from f(*args, **kwargs))
-
- return new_function
-
-
-# It's conservative approach to supported versions, please remove it when we drop the support to Python < 3.4.4
-if hasattr(asyncio, 'ensure_future'):
- # python>=3.4.4
+#FIXME: conservative approach to supported versions, please remove it when we drop the support to Python < 3.4.4
+try:
+ from asyncio import ensure_future
asyncio_ensure_future = asyncio.ensure_future
-else:
- # deprecated
- asyncio_ensure_future = asyncio.async
+except ImportError:
+ asyncio_ensure_future = getattr(asyncio, 'async')
diff --git a/gns3server/utils/asyncio/telnet_server.py b/gns3server/utils/asyncio/telnet_server.py
index 1e16d794..604ab914 100644
--- a/gns3server/utils/asyncio/telnet_server.py
+++ b/gns3server/utils/asyncio/telnet_server.py
@@ -214,9 +214,12 @@ class AsyncioTelnetServer:
@asyncio.coroutine
def close(self):
for writer, connection in self._connections.items():
- writer.write_eof()
- yield from writer.drain()
-
+ try:
+ writer.write_eof()
+ yield from writer.drain()
+ except ConnectionResetError:
+ continue
+
@asyncio.coroutine
def client_connected_hook(self):
pass
@@ -319,6 +322,7 @@ class AsyncioTelnetServer:
else:
log.debug("Not supported negotiation sequence, received {} bytes", len(data))
+ @asyncio.coroutine
def _IAC_parser(self, buf, network_reader, network_writer, connection):
"""
Processes and removes any Telnet commands from the buffer.
@@ -421,9 +425,9 @@ if __name__ == '__main__':
loop = asyncio.get_event_loop()
process = loop.run_until_complete(asyncio_ensure_future(asyncio.subprocess.create_subprocess_exec("/bin/sh", "-i",
- stdout=asyncio.subprocess.PIPE,
- stderr=asyncio.subprocess.STDOUT,
- stdin=asyncio.subprocess.PIPE)))
+ stdout=asyncio.subprocess.PIPE,
+ stderr=asyncio.subprocess.STDOUT,
+ stdin=asyncio.subprocess.PIPE)))
server = AsyncioTelnetServer(reader=process.stdout, writer=process.stdin, binary=False, echo=False)
coro = asyncio.start_server(server.run, '127.0.0.1', 4444, loop=loop)
diff --git a/gns3server/web/web_server.py b/gns3server/web/web_server.py
index 5c9b3248..ab6d1ab8 100644
--- a/gns3server/web/web_server.py
+++ b/gns3server/web/web_server.py
@@ -36,8 +36,7 @@ from ..compute import MODULES
from ..compute.port_manager import PortManager
from ..compute.qemu import Qemu
from ..controller import Controller
-
-from gns3server.utils.asyncio import asyncio_ensure_future
+from ..utils.asyncio import asyncio_ensure_future
# do not delete this import
import gns3server.handlers
@@ -139,7 +138,10 @@ class WebServer:
def signal_handler(signame, *args):
log.warning("Server has got signal {}, exiting...".format(signame))
- asyncio_ensure_future(self.shutdown_server())
+ try:
+ asyncio_ensure_future(self.shutdown_server())
+ except asyncio.CancelledError:
+ pass
signals = ["SIGTERM", "SIGINT"]
if sys.platform.startswith("win"):
@@ -304,4 +306,7 @@ class WebServer:
log.warning("TypeError exception in the loop {}".format(e))
finally:
if self._loop.is_running():
- self._loop.run_until_complete(self.shutdown_server())
+ try:
+ self._loop.run_until_complete(self.shutdown_server())
+ except asyncio.CancelledError:
+ pass
diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py
index f51e8c9c..bb0e9779 100644
--- a/tests/compute/docker/test_docker_vm.py
+++ b/tests/compute/docker/test_docker_vm.py
@@ -87,7 +87,7 @@ def test_create(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]) as mock_list_images:
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu:latest")
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
mock.assert_called_with("POST", "containers/create", data={
"Tty": True,
"OpenStdin": True,
@@ -126,7 +126,7 @@ def test_create_with_tag(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]) as mock_list_images:
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu:16.04")
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
mock.assert_called_with("POST", "containers/create", data={
"Tty": True,
"OpenStdin": True,
@@ -168,7 +168,7 @@ def test_create_vnc(loop, project, manager):
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu", console_type="vnc", console=5900)
vm._start_vnc = MagicMock()
vm._display = 42
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
mock.assert_called_with("POST", "containers/create", data={
"Tty": True,
"OpenStdin": True,
@@ -214,7 +214,7 @@ def test_create_with_extra_hosts(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu", extra_hosts=extra_hosts)
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
called_kwargs = mock.call_args[1]
assert "GNS3_EXTRA_HOSTS=199.199.199.1\ttest\n199.199.199.1\ttest2" in called_kwargs["data"]["Env"]
assert vm._extra_hosts == extra_hosts
@@ -232,7 +232,7 @@ def test_create_with_extra_hosts_wrong_format(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response):
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu", extra_hosts=extra_hosts)
with pytest.raises(DockerError):
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
def test_create_with_empty_extra_hosts(loop, project, manager):
@@ -246,7 +246,7 @@ def test_create_with_empty_extra_hosts(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu", extra_hosts=extra_hosts)
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
called_kwargs = mock.call_args[1]
assert len([ e for e in called_kwargs["data"]["Env"] if "GNS3_EXTRA_HOSTS" in e]) == 0
@@ -266,7 +266,7 @@ def test_create_with_project_variables(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu")
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
called_kwargs = mock.call_args[1]
assert "VAR1=" in called_kwargs["data"]["Env"]
assert "VAR2=VAL1" in called_kwargs["data"]["Env"]
@@ -284,7 +284,7 @@ def test_create_start_cmd(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu:latest")
vm._start_command = "/bin/ls"
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
mock.assert_called_with("POST", "containers/create", data={
"Tty": True,
"OpenStdin": True,
@@ -328,7 +328,7 @@ def test_create_environment(loop, project, manager):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu")
vm.environment = "YES=1\nNO=0\nGNS3_MAX_ETHERNET=eth2"
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
assert mock.call_args[1]['data']['Env'] == [
"container=docker",
"GNS3_MAX_ETHERNET=eth0",
@@ -352,7 +352,7 @@ def test_create_environment_with_last_new_line_character(loop, project, manager)
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu")
vm.environment = "YES=1\nNO=0\nGNS3_MAX_ETHERNET=eth2\n"
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
assert mock.call_args[1]['data']['Env'] == [
"container=docker",
"GNS3_MAX_ETHERNET=eth0",
@@ -385,7 +385,7 @@ def test_create_image_not_available(loop, project, manager):
vm._get_image_information.side_effect = information
with asyncio_patch("gns3server.compute.docker.DockerVM.pull_image", return_value=True) as mock_pull:
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
- loop.run_until_complete(asyncio.async(vm.create()))
+ loop.run_until_complete(asyncio.ensure_future(vm.create()))
mock.assert_called_with("POST", "containers/create", data={
"Tty": True,
"OpenStdin": True,
@@ -431,17 +431,17 @@ def test_get_container_state(loop, vm):
}
}
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
- assert loop.run_until_complete(asyncio.async(vm._get_container_state())) == "running"
+ assert loop.run_until_complete(asyncio.ensure_future(vm._get_container_state())) == "running"
response["State"]["Running"] = False
response["State"]["Paused"] = True
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
- assert loop.run_until_complete(asyncio.async(vm._get_container_state())) == "paused"
+ assert loop.run_until_complete(asyncio.ensure_future(vm._get_container_state())) == "paused"
response["State"]["Running"] = False
response["State"]["Paused"] = False
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
- assert loop.run_until_complete(asyncio.async(vm._get_container_state())) == "exited"
+ assert loop.run_until_complete(asyncio.ensure_future(vm._get_container_state())) == "exited"
def test_is_running(loop, vm):
@@ -452,17 +452,17 @@ def test_is_running(loop, vm):
}
}
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
- assert loop.run_until_complete(asyncio.async(vm.is_running())) is False
+ assert loop.run_until_complete(asyncio.ensure_future(vm.is_running())) is False
response["State"]["Running"] = True
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
- assert loop.run_until_complete(asyncio.async(vm.is_running())) is True
+ assert loop.run_until_complete(asyncio.ensure_future(vm.is_running())) is True
def test_pause(loop, vm):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock:
- loop.run_until_complete(asyncio.async(vm.pause()))
+ loop.run_until_complete(asyncio.ensure_future(vm.pause()))
mock.assert_called_with("POST", "containers/e90e34656842/pause")
assert vm.status == "suspended"
@@ -471,7 +471,7 @@ def test_pause(loop, vm):
def test_unpause(loop, vm):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock:
- loop.run_until_complete(asyncio.async(vm.unpause()))
+ loop.run_until_complete(asyncio.ensure_future(vm.unpause()))
mock.assert_called_with("POST", "containers/e90e34656842/unpause")
@@ -491,10 +491,10 @@ def test_start(loop, vm, manager, free_console_port):
vm._start_console = AsyncioMagicMock()
nio = manager.create_nio({"type": "nio_udp", "lport": free_console_port, "rport": free_console_port, "rhost": "127.0.0.1"})
- loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(0, nio)))
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
- loop.run_until_complete(asyncio.async(vm.start()))
+ loop.run_until_complete(asyncio.ensure_future(vm.start()))
mock_query.assert_called_with("POST", "containers/e90e34656842/start")
vm._add_ubridge_connection.assert_called_once_with(nio, 0)
@@ -510,7 +510,7 @@ def test_start_namespace_failed(loop, vm, manager, free_console_port):
vm.adapters = 1
nio = manager.create_nio({"type": "nio_udp", "lport": free_console_port, "rport": free_console_port, "rhost": "127.0.0.1"})
- loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(0, nio)))
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
@@ -520,7 +520,7 @@ def test_start_namespace_failed(loop, vm, manager, free_console_port):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_log", return_value='Hello not available') as mock_log:
with pytest.raises(DockerError):
- loop.run_until_complete(asyncio.async(vm.start()))
+ loop.run_until_complete(asyncio.ensure_future(vm.start()))
mock_query.assert_any_call("POST", "containers/e90e34656842/start")
mock_add_ubridge_connection.assert_called_once_with(nio, 0)
@@ -542,7 +542,7 @@ def test_start_without_nio(loop, vm, manager, free_console_port):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_namespace", return_value=42) as mock_namespace:
with asyncio_patch("gns3server.compute.docker.DockerVM._add_ubridge_connection") as mock_add_ubridge_connection:
with asyncio_patch("gns3server.compute.docker.DockerVM._start_console") as mock_start_console:
- loop.run_until_complete(asyncio.async(vm.start()))
+ loop.run_until_complete(asyncio.ensure_future(vm.start()))
mock_query.assert_called_with("POST", "containers/e90e34656842/start")
assert mock_add_ubridge_connection.called
@@ -555,7 +555,7 @@ def test_start_unpause(loop, vm, manager, free_console_port):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="paused"):
with asyncio_patch("gns3server.compute.docker.DockerVM.unpause", return_value="paused") as mock:
- loop.run_until_complete(asyncio.async(vm.start()))
+ loop.run_until_complete(asyncio.ensure_future(vm.start()))
assert mock.called
assert vm.status == "started"
@@ -563,7 +563,7 @@ def test_start_unpause(loop, vm, manager, free_console_port):
def test_restart(loop, vm):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock:
- loop.run_until_complete(asyncio.async(vm.restart()))
+ loop.run_until_complete(asyncio.ensure_future(vm.restart()))
mock.assert_called_with("POST", "containers/e90e34656842/restart")
@@ -576,7 +576,7 @@ def test_stop(loop, vm):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="running"):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
- loop.run_until_complete(asyncio.async(vm.stop()))
+ loop.run_until_complete(asyncio.ensure_future(vm.stop()))
mock_query.assert_called_with("POST", "containers/e90e34656842/stop", params={"t": 5})
assert mock.stop.called
assert vm._ubridge_hypervisor is None
@@ -588,7 +588,7 @@ def test_stop_paused_container(loop, vm):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="paused"):
with asyncio_patch("gns3server.compute.docker.DockerVM.unpause") as mock_unpause:
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
- loop.run_until_complete(asyncio.async(vm.stop()))
+ loop.run_until_complete(asyncio.ensure_future(vm.stop()))
mock_query.assert_called_with("POST", "containers/e90e34656842/stop", params={"t": 5})
assert mock_unpause.called
@@ -606,7 +606,7 @@ def test_update(loop, vm):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]) as mock_list_images:
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock_query:
- loop.run_until_complete(asyncio.async(vm.update()))
+ loop.run_until_complete(asyncio.ensure_future(vm.update()))
mock_query.assert_any_call("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
mock_query.assert_any_call("POST", "containers/create", data={
@@ -656,7 +656,7 @@ def test_update_vnc(loop, vm):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]) as mock_list_images:
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock_query:
- loop.run_until_complete(asyncio.async(vm.update()))
+ loop.run_until_complete(asyncio.ensure_future(vm.update()))
assert vm.console == original_console
assert vm.aux == original_aux
@@ -675,7 +675,7 @@ def test_update_running(loop, vm):
with asyncio_patch("gns3server.compute.docker.Docker.list_images", return_value=[{"image": "ubuntu"}]) as mock_list_images:
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="running"):
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock_query:
- loop.run_until_complete(asyncio.async(vm.update()))
+ loop.run_until_complete(asyncio.ensure_future(vm.update()))
mock_query.assert_any_call("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
mock_query.assert_any_call("POST", "containers/create", data={
@@ -713,7 +713,7 @@ def test_delete(loop, vm):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
- loop.run_until_complete(asyncio.async(vm.delete()))
+ loop.run_until_complete(asyncio.ensure_future(vm.delete()))
mock_query.assert_called_with("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
@@ -723,11 +723,11 @@ def test_close(loop, vm, port_manager):
"rport": 4343,
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
- loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(0, nio)))
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
- loop.run_until_complete(asyncio.async(vm.close()))
+ loop.run_until_complete(asyncio.ensure_future(vm.close()))
mock_query.assert_called_with("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
assert vm._closed is True
@@ -742,7 +742,7 @@ def test_close_vnc(loop, vm, port_manager):
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="stopped"):
with asyncio_patch("gns3server.compute.docker.Docker.query") as mock_query:
- loop.run_until_complete(asyncio.async(vm.close()))
+ loop.run_until_complete(asyncio.ensure_future(vm.close()))
mock_query.assert_called_with("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
assert vm._closed is True
@@ -756,7 +756,7 @@ def test_get_namespace(loop, vm):
}
}
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock_query:
- assert loop.run_until_complete(asyncio.async(vm._get_namespace())) == 42
+ assert loop.run_until_complete(asyncio.ensure_future(vm._get_namespace())) == 42
mock_query.assert_called_with("GET", "containers/e90e34656842/json")
@@ -771,7 +771,7 @@ def test_add_ubridge_connection(loop, vm):
vm._ubridge_hypervisor = MagicMock()
vm._namespace = 42
- loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0)))
+ loop.run_until_complete(asyncio.ensure_future(vm._add_ubridge_connection(nio, 0)))
calls = [
call.send('bridge create bridge0'),
@@ -792,7 +792,7 @@ def test_add_ubridge_connection_none_nio(loop, vm):
vm._ubridge_hypervisor = MagicMock()
vm._namespace = 42
- loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0)))
+ loop.run_until_complete(asyncio.ensure_future(vm._add_ubridge_connection(nio, 0)))
calls = [
call.send('bridge create bridge0'),
@@ -813,7 +813,7 @@ def test_add_ubridge_connection_invalid_adapter_number(loop, vm):
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
with pytest.raises(DockerError):
- loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 12)))
+ loop.run_until_complete(asyncio.ensure_future(vm._add_ubridge_connection(nio, 12)))
def test_add_ubridge_connection_no_free_interface(loop, vm):
@@ -829,7 +829,7 @@ def test_add_ubridge_connection_no_free_interface(loop, vm):
interfaces = ["tap-gns3-e{}".format(index) for index in range(4096)]
with patch("psutil.net_if_addrs", return_value=interfaces):
- loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0)))
+ loop.run_until_complete(asyncio.ensure_future(vm._add_ubridge_connection(nio, 0)))
def test_adapter_add_nio_binding(vm, loop):
@@ -838,7 +838,7 @@ def test_adapter_add_nio_binding(vm, loop):
"rport": 4343,
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
- loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(0, nio)))
assert vm._ethernet_adapters[0].get_nio(0) == nio
@@ -853,9 +853,9 @@ def test_adapter_udpate_nio_binding(vm, loop):
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="running"):
- loop.run_until_complete(asyncio.async(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.async(vm.adapter_update_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_update_nio_binding(0, nio)))
assert vm._ubridge_apply_filters.called
@@ -867,9 +867,9 @@ def test_adapter_udpate_nio_binding_bridge_not_started(vm, loop):
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
with asyncio_patch("gns3server.compute.docker.DockerVM._get_container_state", return_value="running"):
- loop.run_until_complete(asyncio.async(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.async(vm.adapter_update_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_update_nio_binding(0, nio)))
assert vm._ubridge_apply_filters.called is False
@@ -880,7 +880,7 @@ def test_adapter_add_nio_binding_invalid_adapter(vm, loop):
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
with pytest.raises(DockerError):
- loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(12, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(12, nio)))
def test_adapter_remove_nio_binding(vm, loop):
@@ -892,10 +892,10 @@ def test_adapter_remove_nio_binding(vm, loop):
"rport": 4343,
"rhost": "127.0.0.1"}
nio = vm.manager.create_nio(nio)
- loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(0, nio)))
with asyncio_patch("gns3server.compute.docker.DockerVM._ubridge_send") as delete_ubridge_mock:
- loop.run_until_complete(asyncio.async(vm.adapter_remove_nio_binding(0)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_remove_nio_binding(0)))
assert vm._ethernet_adapters[0].get_nio(0) is None
delete_ubridge_mock.assert_any_call('bridge stop bridge0')
delete_ubridge_mock.assert_any_call('bridge remove_nio_udp bridge0 4242 127.0.0.1 4343')
@@ -903,15 +903,15 @@ def test_adapter_remove_nio_binding(vm, loop):
def test_adapter_remove_nio_binding_invalid_adapter(vm, loop):
with pytest.raises(DockerError):
- loop.run_until_complete(asyncio.async(vm.adapter_remove_nio_binding(12)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_remove_nio_binding(12)))
def test_start_capture(vm, tmpdir, manager, free_console_port, loop):
output_file = str(tmpdir / "test.pcap")
nio = manager.create_nio({"type": "nio_udp", "lport": free_console_port, "rport": free_console_port, "rhost": "127.0.0.1"})
- loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(0, nio)))
- loop.run_until_complete(asyncio.async(vm.start_capture(0, output_file)))
+ loop.run_until_complete(asyncio.ensure_future(vm.adapter_add_nio_binding(0, nio)))
+ loop.run_until_complete(asyncio.ensure_future(vm.start_capture(0, output_file)))
assert vm._ethernet_adapters[0].get_nio(0).capturing
@@ -919,10 +919,10 @@ def test_stop_capture(vm, tmpdir, manager, free_console_port, loop):
output_file = str(tmpdir / "test.pcap")
nio = manager.create_nio({"type": "nio_udp", "lport": free_console_port, "rport": free_console_port, "rhost": "127.0.0.1"})
- loop.run_until_complete(asyncio.async(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(vm.start_capture(0, output_file))
assert vm._ethernet_adapters[0].get_nio(0).capturing
- loop.run_until_complete(asyncio.async(vm.stop_capture(0)))
+ loop.run_until_complete(asyncio.ensure_future(vm.stop_capture(0)))
assert vm._ethernet_adapters[0].get_nio(0).capturing is False
@@ -935,7 +935,7 @@ def test_get_log(loop, vm):
mock_query.read = read
with asyncio_patch("gns3server.compute.docker.Docker.http_query", return_value=mock_query) as mock:
- images = loop.run_until_complete(asyncio.async(vm._get_log()))
+ images = loop.run_until_complete(asyncio.ensure_future(vm._get_log()))
mock.assert_called_with("GET", "containers/e90e34656842/logs", params={"stderr": 1, "stdout": 1}, data={})
@@ -944,7 +944,7 @@ def test_get_image_informations(project, manager, loop):
}
with asyncio_patch("gns3server.compute.docker.Docker.query", return_value=response) as mock:
vm = DockerVM("test", str(uuid.uuid4()), project, manager, "ubuntu")
- loop.run_until_complete(asyncio.async(vm._get_image_information()))
+ loop.run_until_complete(asyncio.ensure_future(vm._get_image_information()))
mock.assert_called_with("GET", "images/ubuntu:latest/json")
@@ -974,7 +974,7 @@ def test_start_vnc(vm, loop):
with patch("shutil.which", return_value="/bin/x"):
with asyncio_patch("gns3server.compute.docker.docker_vm.wait_for_file_creation") as mock_wait:
with asyncio_patch("asyncio.create_subprocess_exec") as mock_exec:
- loop.run_until_complete(asyncio.async(vm._start_vnc()))
+ loop.run_until_complete(asyncio.ensure_future(vm._start_vnc()))
assert vm._display is not None
mock_exec.assert_any_call("Xvfb", "-nolisten", "tcp", ":{}".format(vm._display), "-screen", "0", "1280x1024x16")
mock_exec.assert_any_call("x11vnc", "-forever", "-nopw", "-shared", "-geometry", "1280x1024", "-display", "WAIT:{}".format(vm._display), "-rfbport", str(vm.console), "-rfbportv6", str(vm.console), "-noncache", "-listen", "127.0.0.1")
@@ -983,13 +983,13 @@ def test_start_vnc(vm, loop):
def test_start_vnc_xvfb_missing(vm, loop):
with pytest.raises(DockerError):
- loop.run_until_complete(asyncio.async(vm._start_vnc()))
+ loop.run_until_complete(asyncio.ensure_future(vm._start_vnc()))
def test_start_aux(vm, loop):
with asyncio_patch("asyncio.subprocess.create_subprocess_exec", return_value=MagicMock()) as mock_exec:
- loop.run_until_complete(asyncio.async(vm._start_aux()))
+ loop.run_until_complete(asyncio.ensure_future(vm._start_aux()))
mock_exec.assert_called_with('docker', 'exec', '-i', 'e90e34656842', '/gns3/bin/busybox', 'script', '-qfc', 'while true; do TERM=vt100 /gns3/bin/busybox sh; done', '/dev/null', stderr=asyncio.subprocess.STDOUT, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE)
@@ -1051,5 +1051,5 @@ def test_read_console_output_with_binary_mode(vm, loop):
output_stream = MagicMock()
with asyncio_patch('gns3server.compute.docker.docker_vm.DockerVM.stop'):
- loop.run_until_complete(asyncio.async(vm._read_console_output(input_stream, output_stream)))
+ loop.run_until_complete(asyncio.ensure_future(vm._read_console_output(input_stream, output_stream)))
output_stream.feed_data.assert_called_once_with(b"test")
diff --git a/tests/compute/qemu/test_qemu_vm.py b/tests/compute/qemu/test_qemu_vm.py
index 86ed8902..5d6c0326 100644
--- a/tests/compute/qemu/test_qemu_vm.py
+++ b/tests/compute/qemu/test_qemu_vm.py
@@ -166,9 +166,9 @@ def test_termination_callback(vm, async_run):
async_run(vm._termination_callback(0))
assert vm.status == "stopped"
- async_run(queue.get(0)) # Ping
+ async_run(queue.get(1)) # Ping
- (action, event, kwargs) = async_run(queue.get(0))
+ (action, event, kwargs) = async_run(queue.get(1))
assert action == "node.updated"
assert event == vm
@@ -186,7 +186,7 @@ def test_termination_callback_error(vm, tmpdir, async_run):
async_run(vm._termination_callback(1))
assert vm.status == "stopped"
- async_run(queue.get(0)) # Ping
+ async_run(queue.get(1)) # Ping
(action, event, kwargs) = queue.get_nowait()
assert action == "node.updated"
diff --git a/tests/compute/test_project.py b/tests/compute/test_project.py
index 32004c41..1dfdab16 100644
--- a/tests/compute/test_project.py
+++ b/tests/compute/test_project.py
@@ -210,5 +210,5 @@ def test_emit(async_run):
def test_update_project(loop):
variables = [{"name": "TEST", "value": "VAL"}]
project = Project(project_id=str(uuid.uuid4()))
- loop.run_until_complete(asyncio.async(project.update(variables=variables)))
+ loop.run_until_complete(asyncio.ensure_future(project.update(variables=variables)))
assert project.variables == variables
diff --git a/tests/compute/traceng/test_traceng_vm.py b/tests/compute/traceng/test_traceng_vm.py
index bbf8df55..2f2133ef 100644
--- a/tests/compute/traceng/test_traceng_vm.py
+++ b/tests/compute/traceng/test_traceng_vm.py
@@ -56,7 +56,7 @@ def test_vm_invalid_traceng_path(vm, manager, loop):
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.async(vm.start()))
+ loop.run_until_complete(asyncio.ensure_future(vm.start()))
assert vm.name == "test"
assert vm.id == "00010203-0405-0607-0809-0a0b0c0d0e0e"
@@ -66,13 +66,13 @@ def test_start(loop, vm, async_run):
process.returncode = None
with NotificationManager.instance().queue() as queue:
- async_run(queue.get(0)) # Ping
+ async_run(queue.get(1)) # Ping
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=process) as mock_exec:
- loop.run_until_complete(asyncio.async(vm.start("192.168.1.2")))
+ loop.run_until_complete(asyncio.ensure_future(vm.start("192.168.1.2")))
assert mock_exec.call_args[0] == (vm._traceng_path(),
'-u',
'-c',
@@ -88,7 +88,7 @@ def test_start(loop, vm, async_run):
'192.168.1.2')
assert vm.is_running()
assert vm.command_line == ' '.join(mock_exec.call_args[0])
- (action, event, kwargs) = async_run(queue.get(0))
+ (action, event, kwargs) = async_run(queue.get(1))
assert action == "node.updated"
assert event == vm
@@ -115,15 +115,15 @@ def test_stop(loop, vm, async_run):
assert vm.is_running()
with asyncio_patch("gns3server.utils.asyncio.wait_for_process_termination"):
- loop.run_until_complete(asyncio.async(vm.stop()))
+ loop.run_until_complete(asyncio.ensure_future(vm.stop()))
assert vm.is_running() is False
process.terminate.assert_called_with()
- async_run(queue.get(0)) # Ping
- async_run(queue.get(0)) # Started
+ async_run(queue.get(1)) # Ping
+ async_run(queue.get(1)) # Started
- (action, event, kwargs) = async_run(queue.get(0))
+ (action, event, kwargs) = async_run(queue.get(1))
assert action == "node.updated"
assert event == vm
@@ -175,5 +175,5 @@ 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.async(vm.close()))
+ loop.run_until_complete(asyncio.ensure_future(vm.close()))
assert vm.is_running() is False
diff --git a/tests/compute/vpcs/test_vpcs_vm.py b/tests/compute/vpcs/test_vpcs_vm.py
index f7862516..238b1d52 100644
--- a/tests/compute/vpcs/test_vpcs_vm.py
+++ b/tests/compute/vpcs/test_vpcs_vm.py
@@ -91,7 +91,7 @@ def test_start(loop, vm, async_run):
process.returncode = None
with NotificationManager.instance().queue() as queue:
- async_run(queue.get(0)) # Ping
+ async_run(queue.get(1)) # Ping
with asyncio_patch("gns3server.compute.vpcs.vpcs_vm.VPCSVM._check_requirements", return_value=True):
with asyncio_patch("asyncio.create_subprocess_exec", return_value=process) as mock_exec:
@@ -113,7 +113,7 @@ def test_start(loop, vm, async_run):
'127.0.0.1')
assert vm.is_running()
assert vm.command_line == ' '.join(mock_exec.call_args[0])
- (action, event, kwargs) = async_run(queue.get(0))
+ (action, event, kwargs) = async_run(queue.get(1))
assert action == "node.updated"
assert event == vm
@@ -177,10 +177,10 @@ def test_stop(loop, vm, async_run):
else:
process.terminate.assert_called_with()
- async_run(queue.get(0)) # Ping
- async_run(queue.get(0)) # Started
+ async_run(queue.get(1)) # Ping
+ async_run(queue.get(1)) # Started
- (action, event, kwargs) = async_run(queue.get(0))
+ (action, event, kwargs) = async_run(queue.get(1))
assert action == "node.updated"
assert event == vm
diff --git a/tests/conftest.py b/tests/conftest.py
index da83b431..0fcdd055 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -104,7 +104,7 @@ def http_server(request, loop, port_manager, monkeypatch, controller):
monkeypatch.setattr('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.close', lambda self: True)
loop.run_until_complete(instance.unload())
srv.close()
- srv.wait_closed()
+ loop.run_until_complete(srv.wait_closed())
@pytest.fixture
diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py
index aecf69e6..2a929872 100644
--- a/tests/controller/test_compute.py
+++ b/tests/controller/test_compute.py
@@ -277,6 +277,7 @@ def test_json(compute):
"cpu_usage_percent": None,
"memory_usage_percent": None,
"connected": True,
+ "last_error": None,
"capabilities": {
"version": None,
"node_types": []
diff --git a/tests/handlers/api/controller/test_compute.py b/tests/handlers/api/controller/test_compute.py
index 57cbdfb7..36b3f5ac 100644
--- a/tests/handlers/api/controller/test_compute.py
+++ b/tests/handlers/api/controller/test_compute.py
@@ -131,6 +131,7 @@ def test_compute_list(http_controller, controller):
'name': 'My super server',
'cpu_usage_percent': None,
'memory_usage_percent': None,
+ 'last_error': None,
'capabilities': {
'version': None,
'node_types': []
diff --git a/tests/utils/test_asyncio.py b/tests/utils/test_asyncio.py
index 942bf455..225cb9d6 100644
--- a/tests/utils/test_asyncio.py
+++ b/tests/utils/test_asyncio.py
@@ -21,7 +21,7 @@ import pytest
import sys
from unittest.mock import MagicMock
-from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output, wait_for_process_termination, locked_coroutine
+from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output, wait_for_process_termination, locking
from tests.utils import AsyncioMagicMock
@@ -84,7 +84,8 @@ def test_lock_decorator(loop):
def __init__(self):
self._test_val = 0
- @locked_coroutine
+ @locking
+ @asyncio.coroutine
def method_to_lock(self):
res = self._test_val
yield from asyncio.sleep(0.1)