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

New Dynamips integration part 3

This commit is contained in:
Jeremy 2015-02-11 19:21:34 -07:00
parent 37945585b9
commit 79a57ca420
51 changed files with 1257 additions and 2386 deletions

View File

@ -186,7 +186,7 @@ class Config(object):
""" """
Singleton to return only on instance of Config. Singleton to return only on instance of Config.
:params files: Array of configuration files (optionnal) :params files: Array of configuration files (optional)
:returns: instance of Config :returns: instance of Config
""" """

View File

@ -15,10 +15,12 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import asyncio
from ..web.route import Route from ..web.route import Route
from ..schemas.dynamips import ROUTER_CREATE_SCHEMA from ..schemas.dynamips import VM_CREATE_SCHEMA
from ..schemas.dynamips import ROUTER_OBJECT_SCHEMA from ..schemas.dynamips import VM_UPDATE_SCHEMA
from ..schemas.dynamips import VM_OBJECT_SCHEMA
from ..modules.dynamips import Dynamips from ..modules.dynamips import Dynamips
from ..modules.project_manager import ProjectManager from ..modules.project_manager import ProjectManager
@ -31,7 +33,7 @@ class DynamipsHandler:
@classmethod @classmethod
@Route.post( @Route.post(
r"/projects/{project_id}/dynamips/routers", r"/projects/{project_id}/dynamips/vms",
parameters={ parameters={
"project_id": "UUID for the project" "project_id": "UUID for the project"
}, },
@ -40,20 +42,194 @@ class DynamipsHandler:
400: "Invalid request", 400: "Invalid request",
409: "Conflict" 409: "Conflict"
}, },
description="Create a new Dynamips router instance", description="Create a new Dynamips VM instance",
input=ROUTER_CREATE_SCHEMA) input=VM_CREATE_SCHEMA,
#output=ROUTER_OBJECT_SCHEMA) output=VM_OBJECT_SCHEMA)
def create(request, response): def create(request, response):
dynamips_manager = Dynamips.instance() dynamips_manager = Dynamips.instance()
vm = yield from dynamips_manager.create_vm(request.json.pop("name"), vm = yield from dynamips_manager.create_vm(request.json.pop("name"),
request.match_info["project_id"], request.match_info["project_id"],
request.json.get("vm_id"), request.json.get("vm_id"),
request.json.get("dynamips_id"),
request.json.pop("platform")) request.json.pop("platform"))
#for name, value in request.json.items(): # set VM options
# if hasattr(vm, name) and getattr(vm, name) != value: for name, value in request.json.items():
# setattr(vm, name, value) if hasattr(vm, name) and getattr(vm, name) != value:
setter = getattr(vm, "set_{}".format(name))
if asyncio.iscoroutinefunction(vm.close):
yield from setter(value)
else:
setter(value)
response.set_status(201) response.set_status(201)
response.json(vm) response.json(vm)
@classmethod
@Route.get(
r"/projects/{project_id}/dynamips/vms/{vm_id}",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
200: "Success",
400: "Invalid request",
404: "Instance doesn't exist"
},
description="Get a Dynamips VM instance",
output=VM_OBJECT_SCHEMA)
def show(request, response):
dynamips_manager = Dynamips.instance()
vm = dynamips_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"])
response.json(vm)
@classmethod
@Route.put(
r"/projects/{project_id}/dynamips/vms/{vm_id}",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
200: "Instance updated",
400: "Invalid request",
404: "Instance doesn't exist",
409: "Conflict"
},
description="Update a Dynamips VM instance",
input=VM_UPDATE_SCHEMA,
output=VM_OBJECT_SCHEMA)
def update(request, response):
dynamips_manager = Dynamips.instance()
vm = dynamips_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"])
# FIXME: set options
#for name, value in request.json.items():
# if hasattr(vm, name) and getattr(vm, name) != value:
# setattr(vm, name, value)
response.json(vm)
@classmethod
@Route.delete(
r"/projects/{project_id}/dynamips/vms/{vm_id}",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
204: "Instance deleted",
400: "Invalid request",
404: "Instance doesn't exist"
},
description="Delete a Dynamips VM instance")
def delete(request, response):
# check the project_id exists
ProjectManager.instance().get_project(request.match_info["project_id"])
yield from Dynamips.instance().delete_vm(request.match_info["vm_id"])
response.set_status(204)
@classmethod
@Route.post(
r"/projects/{project_id}/dynamips/vms/{vm_id}/start",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
204: "Instance started",
400: "Invalid request",
404: "Instance doesn't exist"
},
description="Start a Dynamips VM instance")
def start(request, response):
dynamips_manager = Dynamips.instance()
vm = dynamips_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"])
yield from vm.start()
response.set_status(204)
@classmethod
@Route.post(
r"/projects/{project_id}/dynamips/vms/{vm_id}/stop",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
204: "Instance stopped",
400: "Invalid request",
404: "Instance doesn't exist"
},
description="Stop a Dynamips VM instance")
def stop(request, response):
dynamips_manager = Dynamips.instance()
vm = dynamips_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"])
yield from vm.stop()
response.set_status(204)
@classmethod
@Route.post(
r"/projects/{project_id}/dynamips/vms/{vm_id}/suspend",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
204: "Instance suspended",
400: "Invalid request",
404: "Instance doesn't exist"
},
description="Suspend a Dynamips VM instance")
def suspend(request, response):
dynamips_manager = Dynamips.instance()
vm = dynamips_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"])
yield from vm.suspend()
response.set_status(204)
@classmethod
@Route.post(
r"/projects/{project_id}/dynamips/vms/{vm_id}/resume",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
204: "Instance resumed",
400: "Invalid request",
404: "Instance doesn't exist"
},
description="Resume a suspended Dynamips VM instance")
def suspend(request, response):
dynamips_manager = Dynamips.instance()
vm = dynamips_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"])
yield from vm.resume()
response.set_status(204)
@classmethod
@Route.post(
r"/projects/{project_id}/dynamips/vms/{vm_id}/reload",
parameters={
"project_id": "UUID for the project",
"vm_id": "UUID for the instance"
},
status_codes={
204: "Instance reloaded",
400: "Invalid request",
404: "Instance doesn't exist"
},
description="Reload a Dynamips VM instance")
def reload(request, response):
dynamips_manager = Dynamips.instance()
vm = dynamips_manager.get_vm(request.match_info["vm_id"], project_id=request.match_info["project_id"])
yield from vm.reload()
response.set_status(204)

View File

@ -19,81 +19,18 @@
Dynamips server module. Dynamips server module.
""" """
import aiohttp
import sys import sys
import os import os
import base64
import tempfile
import shutil import shutil
import glob
import socket import socket
from gns3server.config import Config
# from .hypervisor import Hypervisor
# from .hypervisor_manager import HypervisorManager
# from .dynamips_error import DynamipsError
#
# # Nodes
# from .nodes.router import Router
# from .nodes.c1700 import C1700
# from .nodes.c2600 import C2600
# from .nodes.c2691 import C2691
# from .nodes.c3600 import C3600
# from .nodes.c3725 import C3725
# from .nodes.c3745 import C3745
# from .nodes.c7200 import C7200
# from .nodes.bridge import Bridge
# from .nodes.ethernet_switch import EthernetSwitch
# from .nodes.atm_switch import ATMSwitch
# from .nodes.atm_bridge import ATMBridge
# from .nodes.frame_relay_switch import FrameRelaySwitch
# from .nodes.hub import Hub
#
# # Adapters
# from .adapters.c7200_io_2fe import C7200_IO_2FE
# from .adapters.c7200_io_fe import C7200_IO_FE
# from .adapters.c7200_io_ge_e import C7200_IO_GE_E
# from .adapters.nm_16esw import NM_16ESW
# from .adapters.nm_1e import NM_1E
# from .adapters.nm_1fe_tx import NM_1FE_TX
# from .adapters.nm_4e import NM_4E
# from .adapters.nm_4t import NM_4T
# from .adapters.pa_2fe_tx import PA_2FE_TX
# from .adapters.pa_4e import PA_4E
# from .adapters.pa_4t import PA_4T
# from .adapters.pa_8e import PA_8E
# from .adapters.pa_8t import PA_8T
# from .adapters.pa_a1 import PA_A1
# from .adapters.pa_fe_tx import PA_FE_TX
# from .adapters.pa_ge import PA_GE
# from .adapters.pa_pos_oc3 import PA_POS_OC3
# from .adapters.wic_1t import WIC_1T
# from .adapters.wic_2t import WIC_2T
# from .adapters.wic_1enet import WIC_1ENET
#
# # NIOs
# from .nios.nio_udp import NIO_UDP
# from .nios.nio_udp_auto import NIO_UDP_auto
# from .nios.nio_unix import NIO_UNIX
# from .nios.nio_vde import NIO_VDE
# from .nios.nio_tap import NIO_TAP
# from .nios.nio_generic_ethernet import NIO_GenericEthernet
# from .nios.nio_linux_ethernet import NIO_LinuxEthernet
# from .nios.nio_fifo import NIO_FIFO
# from .nios.nio_mcast import NIO_Mcast
# from .nios.nio_null import NIO_Null
#
# from .backends import vm
# from .backends import ethsw
# from .backends import ethhub
# from .backends import frsw
# from .backends import atmsw
import time import time
import asyncio import asyncio
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
from gns3server.utils.interfaces import get_windows_interfaces
from pkg_resources import parse_version from pkg_resources import parse_version
from ..base_manager import BaseManager from ..base_manager import BaseManager
from .dynamips_error import DynamipsError from .dynamips_error import DynamipsError
@ -101,6 +38,18 @@ from .hypervisor import Hypervisor
from .nodes.router import Router from .nodes.router import Router
from .dynamips_vm import DynamipsVM from .dynamips_vm import DynamipsVM
# NIOs
from .nios.nio_udp import NIOUDP
from .nios.nio_udp_auto import NIOUDPAuto
from .nios.nio_unix import NIOUNIX
from .nios.nio_vde import NIOVDE
from .nios.nio_tap import NIOTAP
from .nios.nio_generic_ethernet import NIOGenericEthernet
from .nios.nio_linux_ethernet import NIOLinuxEthernet
from .nios.nio_fifo import NIOFIFO
from .nios.nio_mcast import NIOMcast
from .nios.nio_null import NIONull
class Dynamips(BaseManager): class Dynamips(BaseManager):
@ -113,7 +62,35 @@ class Dynamips(BaseManager):
# FIXME: temporary # FIXME: temporary
self._working_dir = "/tmp" self._working_dir = "/tmp"
self._dynamips_path = "/usr/bin/dynamips"
@asyncio.coroutine
def unload(self):
yield from BaseManager.unload(self)
Router.reset()
# files = glob.glob(os.path.join(self._working_dir, "dynamips", "*.ghost"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "*_lock"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "ilt_*"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_rommon_vars"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_ssa"))
# for file in files:
# try:
# log.debug("deleting file {}".format(file))
# os.remove(file)
# except OSError as e:
# log.warn("could not delete file {}: {}".format(file, e))
# continue
@property
def dynamips_path(self):
"""
Returns the path to Dynamips.
:returns: path
"""
return self._dynamips_path
def find_dynamips(self): def find_dynamips(self):
@ -168,6 +145,9 @@ class Dynamips(BaseManager):
:returns: the new hypervisor instance :returns: the new hypervisor instance
""" """
if not self._dynamips_path:
self.find_dynamips()
try: try:
# let the OS find an unused port for the Dynamips hypervisor # let the OS find an unused port for the Dynamips hypervisor
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
@ -190,323 +170,97 @@ class Dynamips(BaseManager):
return hypervisor return hypervisor
def create_nio(self, executable, nio_settings):
"""
Creates a new NIO.
:param nio_settings: information to create the NIO
:returns: a NIO object
"""
nio = None
if nio_settings["type"] == "nio_udp":
lport = nio_settings["lport"]
rhost = nio_settings["rhost"]
rport = nio_settings["rport"]
try:
# TODO: handle IPv6
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.connect((rhost, rport))
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
nio = NIOUDP(lport, rhost, rport)
elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"]
if not self._has_privileged_access(executable):
raise aiohttp.web.HTTPForbidden(text="{} has no privileged access to {}.".format(executable, tap_device))
nio = NIOTAP(tap_device)
assert nio is not None
return nio
def create_nio(self, node, nio_settings):
"""
Creates a new NIO.
:param node: Dynamips node instance
:param nio_settings: information to create the NIO
:returns: a NIO object
"""
nio = None
if nio_settings["type"] == "nio_udp":
lport = nio_settings["lport"]
rhost = nio_settings["rhost"]
rport = nio_settings["rport"]
try:
#TODO: handle IPv6
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.connect((rhost, rport))
except OSError as e:
raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
# check if we have an allocated NIO UDP auto
nio = node.hypervisor.get_nio_udp_auto(lport)
if not nio:
# otherwise create an NIO UDP
nio = NIOUDP(node.hypervisor, lport, rhost, rport)
else:
nio.connect(rhost, rport)
elif nio_settings["type"] == "nio_generic_ethernet":
ethernet_device = nio_settings["ethernet_device"]
if sys.platform.startswith("win"):
# replace the interface name by the GUID on Windows
interfaces = get_windows_interfaces()
npf_interface = None
for interface in interfaces:
if interface["name"] == ethernet_device:
npf_interface = interface["id"]
if not npf_interface:
raise DynamipsError("Could not find interface {} on this host".format(ethernet_device))
else:
ethernet_device = npf_interface
nio = NIOGenericEthernet(node.hypervisor, ethernet_device)
elif nio_settings["type"] == "nio_linux_ethernet":
if sys.platform.startswith("win"):
raise DynamipsError("This NIO type is not supported on Windows")
ethernet_device = nio_settings["ethernet_device"]
nio = NIOLinuxEthernet(node.hypervisor, ethernet_device)
elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"]
nio = NIOTAP(node.hypervisor, tap_device)
elif nio_settings["type"] == "nio_unix":
local_file = nio_settings["local_file"]
remote_file = nio_settings["remote_file"]
nio = NIOUNIX(node.hypervisor, local_file, remote_file)
elif nio_settings["type"] == "nio_vde":
control_file = nio_settings["control_file"]
local_file = nio_settings["local_file"]
nio = NIOVDE(node.hypervisor, control_file, local_file)
elif nio_settings["type"] == "nio_null":
nio = NIONull(node.hypervisor)
return nio
# class Dynamips(IModule):
# """
# Dynamips module.
#
# :param name: module name
# :param args: arguments for the module
# :param kwargs: named arguments for the module
# """
#
# def stop(self, signum=None):
# """
# Properly stops the module.
#
# :param signum: signal number (if called by the signal handler)
# """
#
# if not sys.platform.startswith("win32"):
# self._callback.stop()
#
# # automatically save configs for all router instances
# for router_id in self._routers:
# router = self._routers[router_id]
# try:
# router.save_configs()
# except DynamipsError:
# continue
#
# # stop all Dynamips hypervisors
# if self._hypervisor_manager:
# self._hypervisor_manager.stop_all_hypervisors()
#
# self.delete_dynamips_files()
# IModule.stop(self, signum) # this will stop the I/O loop
#
# def get_device_instance(self, device_id, instance_dict):
# """
# Returns a device instance.
#
# :param device_id: device identifier
# :param instance_dict: dictionary containing the instances
#
# :returns: device instance
# """
#
# if device_id not in instance_dict:
# log.debug("device ID {} doesn't exist".format(device_id), exc_info=1)
# self.send_custom_error("Device ID {} doesn't exist".format(device_id))
# return None
# return instance_dict[device_id]
#
# def delete_dynamips_files(self):
# """
# Deletes useless Dynamips files from the working directory
# """
#
# files = glob.glob(os.path.join(self._working_dir, "dynamips", "*.ghost"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "*_lock"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "ilt_*"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_rommon_vars"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_ssa"))
# for file in files:
# try:
# log.debug("deleting file {}".format(file))
# os.remove(file)
# except OSError as e:
# log.warn("could not delete file {}: {}".format(file, e))
# continue
#
# @IModule.route("dynamips.reset")
# def reset(self, request=None):
# """
# Resets the module (JSON-RPC notification).
#
# :param request: JSON request (not used)
# """
#
# # automatically save configs for all router instances
# for router_id in self._routers:
# router = self._routers[router_id]
# try:
# router.save_configs()
# except DynamipsError:
# continue
#
# # stop all Dynamips hypervisors
# if self._hypervisor_manager:
# self._hypervisor_manager.stop_all_hypervisors()
#
# # resets the instance counters
# Router.reset()
# EthernetSwitch.reset()
# Hub.reset()
# FrameRelaySwitch.reset()
# ATMSwitch.reset()
# NIO_UDP.reset()
# NIO_UDP_auto.reset()
# NIO_UNIX.reset()
# NIO_VDE.reset()
# NIO_TAP.reset()
# NIO_GenericEthernet.reset()
# NIO_LinuxEthernet.reset()
# NIO_FIFO.reset()
# NIO_Mcast.reset()
# NIO_Null.reset()
#
# self._routers.clear()
# self._ethernet_switches.clear()
# self._frame_relay_switches.clear()
# self._atm_switches.clear()
#
# self.delete_dynamips_files()
#
# self._hypervisor_manager = None
# self._working_dir = self._projects_dir
# log.info("dynamips module has been reset")
#
# def start_hypervisor_manager(self):
# """
# Starts the hypervisor manager.
# """
#
# # check if Dynamips path exists
# if not os.path.isfile(self._dynamips):
# raise DynamipsError("Dynamips executable {} doesn't exist".format(self._dynamips))
#
# # check if Dynamips is executable
# if not os.access(self._dynamips, os.X_OK):
# raise DynamipsError("Dynamips {} is not executable".format(self._dynamips))
#
# workdir = os.path.join(self._working_dir, "dynamips")
# try:
# os.makedirs(workdir)
# except FileExistsError:
# pass
# except OSError as e:
# raise DynamipsError("Could not create working directory {}".format(e))
#
# # check if the working directory is writable
# if not os.access(workdir, os.W_OK):
# raise DynamipsError("Cannot write to working directory {}".format(workdir))
#
# log.info("starting the hypervisor manager with Dynamips working directory set to '{}'".format(workdir))
# self._hypervisor_manager = HypervisorManager(self._dynamips, workdir, self._host, self._console_host)
#
# for name, value in self._hypervisor_manager_settings.items():
# if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value:
# setattr(self._hypervisor_manager, name, value)
#
# @IModule.route("dynamips.settings")
# def settings(self, request):
# """
# Set or update settings.
#
# Optional request parameters:
# - path (path to the Dynamips executable)
# - working_dir (path to a working directory)
# - project_name
#
# :param request: JSON request
# """
#
# if request is None:
# self.send_param_error()
# return
#
# log.debug("received request {}".format(request))
#
# #TODO: JSON schema validation
# if not self._hypervisor_manager:
#
# if "path" in request:
# self._dynamips = request.pop("path")
#
# if "working_dir" in request:
# self._working_dir = request.pop("working_dir")
# log.info("this server is local")
# else:
# self._working_dir = os.path.join(self._projects_dir, request["project_name"])
# log.info("this server is remote with working directory path to {}".format(self._working_dir))
#
# self._hypervisor_manager_settings = request
#
# else:
# if "project_name" in request:
# # for remote server
# new_working_dir = os.path.join(self._projects_dir, request["project_name"])
#
# if self._projects_dir != self._working_dir != new_working_dir:
#
# # trick to avoid file locks by Dynamips on Windows
# if sys.platform.startswith("win"):
# self._hypervisor_manager.working_dir = tempfile.gettempdir()
#
# if not os.path.isdir(new_working_dir):
# try:
# self.delete_dynamips_files()
# shutil.move(self._working_dir, new_working_dir)
# except OSError as e:
# log.error("could not move working directory from {} to {}: {}".format(self._working_dir,
# new_working_dir,
# e))
# return
#
# elif "working_dir" in request:
# # for local server
# new_working_dir = request.pop("working_dir")
#
# try:
# self._hypervisor_manager.working_dir = new_working_dir
# except DynamipsError as e:
# log.error("could not change working directory: {}".format(e))
# return
#
# self._working_dir = new_working_dir
#
# # apply settings to the hypervisor manager
# for name, value in request.items():
# if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value:
# setattr(self._hypervisor_manager, name, value)
#
# @IModule.route("dynamips.echo")
# def echo(self, request):
# """
# Echo end point for testing purposes.
#
# :param request: JSON request
# """
#
# if request is None:
# self.send_param_error()
# else:
# log.debug("received request {}".format(request))
# self.send_response(request)
#
# def create_nio(self, node, request):
# """
# Creates a new NIO.
#
# :param node: node requesting the NIO
# :param request: the original request with the
# necessary information to create the NIO
#
# :returns: a NIO object
# """
#
# nio = None
# if request["nio"]["type"] == "nio_udp":
# lport = request["nio"]["lport"]
# rhost = request["nio"]["rhost"]
# rport = request["nio"]["rport"]
# try:
# #TODO: handle IPv6
# with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
# sock.connect((rhost, rport))
# except OSError as e:
# raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
# # check if we have an allocated NIO UDP auto
# nio = node.hypervisor.get_nio_udp_auto(lport)
# if not nio:
# # otherwise create an NIO UDP
# nio = NIO_UDP(node.hypervisor, lport, rhost, rport)
# else:
# nio.connect(rhost, rport)
# elif request["nio"]["type"] == "nio_generic_ethernet":
# ethernet_device = request["nio"]["ethernet_device"]
# if sys.platform.startswith("win"):
# # replace the interface name by the GUID on Windows
# interfaces = get_windows_interfaces()
# npf_interface = None
# for interface in interfaces:
# if interface["name"] == ethernet_device:
# npf_interface = interface["id"]
# if not npf_interface:
# raise DynamipsError("Could not find interface {} on this host".format(ethernet_device))
# else:
# ethernet_device = npf_interface
# nio = NIO_GenericEthernet(node.hypervisor, ethernet_device)
# elif request["nio"]["type"] == "nio_linux_ethernet":
# if sys.platform.startswith("win"):
# raise DynamipsError("This NIO type is not supported on Windows")
# ethernet_device = request["nio"]["ethernet_device"]
# nio = NIO_LinuxEthernet(node.hypervisor, ethernet_device)
# elif request["nio"]["type"] == "nio_tap":
# tap_device = request["nio"]["tap_device"]
# nio = NIO_TAP(node.hypervisor, tap_device)
# elif request["nio"]["type"] == "nio_unix":
# local_file = request["nio"]["local_file"]
# remote_file = request["nio"]["remote_file"]
# nio = NIO_UNIX(node.hypervisor, local_file, remote_file)
# elif request["nio"]["type"] == "nio_vde":
# control_file = request["nio"]["control_file"]
# local_file = request["nio"]["local_file"]
# nio = NIO_VDE(node.hypervisor, control_file, local_file)
# elif request["nio"]["type"] == "nio_null":
# nio = NIO_Null(node.hypervisor)
# return nio
#
# def allocate_udp_port(self, node):
# """
# Allocates a UDP port in order to create an UDP NIO.
#
# :param node: the node that needs to allocate an UDP port
#
# :returns: dictionary with the allocated host/port info
# """
#
# port = node.hypervisor.allocate_udp_port()
# host = node.hypervisor.host
#
# log.info("{} [id={}] has allocated UDP port {} with host {}".format(node.name,
# node.id,
# port,
# host))
# response = {"lport": port}
# return response
#
# def set_ghost_ios(self, router): # def set_ghost_ios(self, router):
# """ # """
# Manages Ghost IOS support. # Manages Ghost IOS support.

View File

@ -26,7 +26,7 @@ import logging
import asyncio import asyncio
from .dynamips_error import DynamipsError from .dynamips_error import DynamipsError
from .nios.nio_udp_auto import NIO_UDP_auto from .nios.nio_udp_auto import NIOUDPAuto
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -415,7 +415,7 @@ class DynamipsHypervisor:
""" """
# use Dynamips's NIO UDP auto back-end. # use Dynamips's NIO UDP auto back-end.
nio = NIO_UDP_auto(self, self._host, self._udp_start_port_range, self._udp_end_port_range) nio = NIOUDPAuto(self, self._host, self._udp_start_port_range, self._udp_end_port_range)
self._nio_udp_auto_instances[nio.lport] = nio self._nio_udp_auto_instances[nio.lport] = nio
allocated_port = nio.lport allocated_port = nio.lport
return allocated_port return allocated_port

View File

@ -42,9 +42,9 @@ class DynamipsVM:
Factory to create an Router object based on the correct platform. Factory to create an Router object based on the correct platform.
""" """
def __new__(cls, name, vm_id, project, manager, platform, **kwargs): def __new__(cls, name, vm_id, project, manager, dynamips_id, platform, **kwargs):
if platform not in PLATFORMS: if platform not in PLATFORMS:
raise DynamipsError("Unknown router platform: {}".format(platform)) raise DynamipsError("Unknown router platform: {}".format(platform))
return PLATFORMS[platform](name, vm_id, project, manager, **kwargs) return PLATFORMS[platform](name, vm_id, project, manager, dynamips_id, **kwargs)

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_FIFO(NIO): class NIOFIFO(NIO):
""" """
Dynamips FIFO NIO. Dynamips FIFO NIO.
@ -40,8 +40,8 @@ class NIO_FIFO(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_FIFO._instance_count self._id = NIOFIFO._instance_count
NIO_FIFO._instance_count += 1 NIOFIFO._instance_count += 1
self._name = 'nio_fifo' + str(self._id) self._name = 'nio_fifo' + str(self._id)
@classmethod @classmethod

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_GenericEthernet(NIO): class NIOGenericEthernet(NIO):
""" """
Dynamips generic Ethernet NIO. Dynamips generic Ethernet NIO.
@ -41,8 +41,8 @@ class NIO_GenericEthernet(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_GenericEthernet._instance_count self._id = NIOGenericEthernet._instance_count
NIO_GenericEthernet._instance_count += 1 NIOGenericEthernet._instance_count += 1
self._name = 'nio_gen_eth' + str(self._id) self._name = 'nio_gen_eth' + str(self._id)
self._ethernet_device = ethernet_device self._ethernet_device = ethernet_device

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_LinuxEthernet(NIO): class NIOLinuxEthernet(NIO):
""" """
Dynamips Linux Ethernet NIO. Dynamips Linux Ethernet NIO.
@ -41,8 +41,8 @@ class NIO_LinuxEthernet(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_LinuxEthernet._instance_count self._id = NIOLinuxEthernet._instance_count
NIO_LinuxEthernet._instance_count += 1 NIOLinuxEthernet._instance_count += 1
self._name = 'nio_linux_eth' + str(self._id) self._name = 'nio_linux_eth' + str(self._id)
self._ethernet_device = ethernet_device self._ethernet_device = ethernet_device

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_Mcast(NIO): class NIOMcast(NIO):
""" """
Dynamips Linux Ethernet NIO. Dynamips Linux Ethernet NIO.
@ -42,8 +42,8 @@ class NIO_Mcast(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_Mcast._instance_count self._id = NIOMcast._instance_count
NIO_Mcast._instance_count += 1 NIOMcast._instance_count += 1
self._name = 'nio_mcast' + str(self._id) self._name = 'nio_mcast' + str(self._id)
self._group = group self._group = group
self._port = port self._port = port

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_Null(NIO): class NIONull(NIO):
""" """
Dynamips NULL NIO. Dynamips NULL NIO.
@ -40,8 +40,8 @@ class NIO_Null(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_Null._instance_count self._id = NIONull._instance_count
NIO_Null._instance_count += 1 NIONull._instance_count += 1
self._name = 'nio_null' + str(self._id) self._name = 'nio_null' + str(self._id)
@classmethod @classmethod

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_TAP(NIO): class NIOTAP(NIO):
""" """
Dynamips TAP NIO. Dynamips TAP NIO.
@ -41,8 +41,8 @@ class NIO_TAP(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_TAP._instance_count self._id = NIOTAP._instance_count
NIO_TAP._instance_count += 1 NIOTAP._instance_count += 1
self._name = 'nio_tap' + str(self._id) self._name = 'nio_tap' + str(self._id)
self._tap_device = tap_device self._tap_device = tap_device

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_UDP(NIO): class NIOUDP(NIO):
""" """
Dynamips UDP NIO. Dynamips UDP NIO.
@ -43,8 +43,8 @@ class NIO_UDP(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_UDP._instance_count self._id = NIOUDP._instance_count
NIO_UDP._instance_count += 1 NIOUDP._instance_count += 1
self._name = 'nio_udp' + str(self._id) self._name = 'nio_udp' + str(self._id)
self._lport = lport self._lport = lport
self._rhost = rhost self._rhost = rhost

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_UDP_auto(NIO): class NIOUDPAuto(NIO):
""" """
Dynamips auto UDP NIO. Dynamips auto UDP NIO.
@ -43,8 +43,8 @@ class NIO_UDP_auto(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_UDP_auto._instance_count self._id = NIOUDPAuto._instance_count
NIO_UDP_auto._instance_count += 1 NIOUDPAuto._instance_count += 1
self._name = 'nio_udp_auto' + str(self._id) self._name = 'nio_udp_auto' + str(self._id)
self._laddr = laddr self._laddr = laddr

View File

@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_UNIX(NIO): class NIOUNIX(NIO):
""" """
Dynamips UNIX NIO. Dynamips UNIX NIO.
@ -42,8 +42,8 @@ class NIO_UNIX(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_UNIX._instance_count self._id = NIOUNIX._instance_count
NIO_UNIX._instance_count += 1 NIOUNIX._instance_count += 1
self._name = 'nio_unix' + str(self._id) self._name = 'nio_unix' + str(self._id)
self._local_file = local_file self._local_file = local_file
self._remote_file = remote_file self._remote_file = remote_file

View File

@ -25,7 +25,7 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class NIO_VDE(NIO): class NIOVDE(NIO):
""" """
Dynamips VDE NIO. Dynamips VDE NIO.
@ -41,8 +41,8 @@ class NIO_VDE(NIO):
NIO.__init__(self, hypervisor) NIO.__init__(self, hypervisor)
# create an unique ID # create an unique ID
self._id = NIO_VDE._instance_count self._id = NIOVDE._instance_count
NIO_VDE._instance_count += 1 NIOVDE._instance_count += 1
self._name = 'nio_vde' + str(self._id) self._name = 'nio_vde' + str(self._id)
self._control_file = control_file self._control_file = control_file
self._local_file = local_file self._local_file = local_file

View File

@ -37,13 +37,14 @@ class C1700(Router):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param chassis: chassis for this router: :param chassis: chassis for this router:
1720, 1721, 1750, 1751 or 1760 (default = 1720). 1720, 1721, 1750, 1751 or 1760 (default = 1720).
1710 is not supported. 1710 is not supported.
""" """
def __init__(self, name, vm_id, project, manager, chassis="1720"): def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="1720"):
Router.__init__(self, name, vm_id, project, manager, platform="c1700") Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c1700")
# Set default values for this platform # Set default values for this platform
self._ram = 128 self._ram = 128

View File

@ -39,6 +39,7 @@ class C2600(Router):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param chassis: chassis for this router: :param chassis: chassis for this router:
2610, 2611, 2620, 2621, 2610XM, 2611XM 2610, 2611, 2620, 2621, 2610XM, 2611XM
2620XM, 2621XM, 2650XM or 2651XM (default = 2610). 2620XM, 2621XM, 2650XM or 2651XM (default = 2610).
@ -57,8 +58,8 @@ class C2600(Router):
"2650XM": C2600_MB_1FE, "2650XM": C2600_MB_1FE,
"2651XM": C2600_MB_2FE} "2651XM": C2600_MB_2FE}
def __init__(self, name, vm_id, project, manager, chassis="2610"): def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="2610"):
Router.__init__(self, name, vm_id, project, manager, platform="c2600") Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c2600")
# Set default values for this platform # Set default values for this platform
self._ram = 128 self._ram = 128

View File

@ -36,10 +36,11 @@ class C2691(Router):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
""" """
def __init__(self, name, vm_id, project, manager): def __init__(self, name, vm_id, project, manager, dynamips_id):
Router.__init__(self, name, vm_id, project, manager, platform="c2691") Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c2691")
# Set default values for this platform # Set default values for this platform
self._ram = 192 self._ram = 192

View File

@ -36,12 +36,13 @@ class C3600(Router):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param chassis: chassis for this router: :param chassis: chassis for this router:
3620, 3640 or 3660 (default = 3640). 3620, 3640 or 3660 (default = 3640).
""" """
def __init__(self, name, vm_id, project, manager, chassis="3640"): def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="3640"):
Router.__init__(self, name, vm_id, project, manager, platform="c3600") Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3600")
# Set default values for this platform # Set default values for this platform
self._ram = 192 self._ram = 192

View File

@ -36,10 +36,11 @@ class C3725(Router):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
""" """
def __init__(self, name, vm_id, project, manager): def __init__(self, name, vm_id, project, manager, dynamips_id):
Router.__init__(self, name, vm_id, project, manager, platform="c3725") Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3725")
# Set default values for this platform # Set default values for this platform
self._ram = 128 self._ram = 128

View File

@ -36,10 +36,11 @@ class C3745(Router):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
""" """
def __init__(self, name, vm_id, project, manager): def __init__(self, name, vm_id, project, manager, dynamips_id):
Router.__init__(self, name, vm_id, project, manager, platform="c3745") Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3745")
# Set default values for this platform # Set default values for this platform
self._ram = 256 self._ram = 256

View File

@ -39,11 +39,12 @@ class C7200(Router):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param npe: Default NPE :param npe: Default NPE
""" """
def __init__(self, name, vm_id, project, manager, npe="npe-400"): def __init__(self, name, vm_id, project, manager, dynamips_id, npe="npe-400"):
Router.__init__(self, name, vm_id, project, manager, platform="c7200") Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c7200")
# Set default values for this platform # Set default values for this platform
self._ram = 512 self._ram = 512

View File

@ -42,20 +42,22 @@ class Router(BaseVM):
:param vm_id: Router instance identifier :param vm_id: Router instance identifier
:param project: Project instance :param project: Project instance
:param manager: Parent VM Manager :param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param platform: Platform of this router :param platform: Platform of this router
""" """
_instances = [] _dynamips_ids = {}
_status = {0: "inactive", _status = {0: "inactive",
1: "shutting down", 1: "shutting down",
2: "running", 2: "running",
3: "suspended"} 3: "suspended"}
def __init__(self, name, vm_id, project, manager, platform="c7200", ghost_flag=False): def __init__(self, name, vm_id, project, manager, dynamips_id=None, platform="c7200", ghost_flag=False):
super().__init__(name, vm_id, project, manager) super().__init__(name, vm_id, project, manager)
self._hypervisor = None self._hypervisor = None
self._dynamips_id = dynamips_id
self._closed = False self._closed = False
self._name = name self._name = name
self._platform = platform self._platform = platform
@ -81,12 +83,26 @@ class Router(BaseVM):
self._confreg = "0x2102" self._confreg = "0x2102"
self._console = None self._console = None
self._aux = None self._aux = None
self._mac_addr = None self._mac_addr = ""
self._system_id = "FTX0945W0MY" # processor board ID in IOS self._system_id = "FTX0945W0MY" # processor board ID in IOS
self._slots = [] self._slots = []
self._ghost_flag = ghost_flag self._ghost_flag = ghost_flag
if not ghost_flag: if not ghost_flag:
self._dynamips_ids.setdefault(project.id, list())
if not dynamips_id:
# find a Dynamips ID if none is provided (0 < id <= 4096)
self._dynamips_id = 0
for identifier in range(1, 4097):
if identifier not in self._dynamips_ids[project.id]:
self._dynamips_id = identifier
break
if self._dynamips_id == 0:
raise DynamipsError("Maximum number of Dynamips instances reached")
else:
if dynamips_id in self._dynamips_ids[project.id]:
raise DynamipsError("Dynamips identifier {} is already used by another router".format(dynamips_id))
self._dynamips_ids[project.id].append(self._dynamips_id)
if self._console is not None: if self._console is not None:
self._console = self._manager.port_manager.reserve_console_port(self._console) self._console = self._manager.port_manager.reserve_console_port(self._console)
@ -97,12 +113,17 @@ class Router(BaseVM):
self._aux = self._manager.port_manager.reserve_console_port(self._aux) self._aux = self._manager.port_manager.reserve_console_port(self._aux)
else: else:
self._aux = self._manager.port_manager.get_free_console_port() self._aux = self._manager.port_manager.get_free_console_port()
else:
log.info("creating a new ghost IOS file")
self._dynamips_id = 0
self._name = "Ghost"
def __json__(self): def __json__(self):
router_info = {"name": self.name, router_info = {"name": self.name,
"vm_id": self.id, "vm_id": self.id,
"project_id": self.project.id, "project_id": self.project.id,
"dynamips_id": self._dynamips_id,
"platform": self._platform, "platform": self._platform,
"image": self._image, "image": self._image,
"startup_config": self._startup_config, "startup_config": self._startup_config,
@ -138,14 +159,21 @@ class Router(BaseVM):
return router_info return router_info
@classmethod
def reset(cls):
"""
Resets the instance count and the allocated instances list.
"""
cls._dynamips_ids.clear()
@asyncio.coroutine @asyncio.coroutine
def create(self): def create(self):
self._hypervisor = yield from self.manager.start_new_hypervisor() self._hypervisor = yield from self.manager.start_new_hypervisor()
print("{} {} {}".format(self._name, self._id, self._platform))
yield from self._hypervisor.send('vm create "{name}" {id} {platform}'.format(name=self._name, yield from self._hypervisor.send('vm create "{name}" {id} {platform}'.format(name=self._name,
id=1, #FIXME: instance ID! id=self._dynamips_id,
platform=self._platform)) platform=self._platform))
if not self._ghost_flag: if not self._ghost_flag:
@ -270,6 +298,9 @@ class Router(BaseVM):
self._manager.port_manager.release_console_port(self._aux) self._manager.port_manager.release_console_port(self._aux)
self._aux = None self._aux = None
if self._dynamips_id in self._dynamips_ids[self._project.id]:
self._dynamips_ids[self._project.id].remove(self._dynamips_id)
self._closed = True self._closed = True
@asyncio.coroutine @asyncio.coroutine

View File

@ -16,41 +16,102 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
ROUTER_CREATE_SCHEMA = { VM_CREATE_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"description": "Request validation to create a new Dynamips router instance", "description": "Request validation to create a new Dynamips VM instance",
"type": "object", "type": "object",
"properties": { "properties": {
"vm_id": {
"description": "Dynamips VM instance identifier",
"oneOf": [
{"type": "string",
"minLength": 36,
"maxLength": 36,
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"},
{"type": "integer"} # for legacy projects
]
},
"dynamips_id": {
"description": "ID to use with Dynamips",
"type": "integer"
},
"name": { "name": {
"description": "Router name", "description": "Dynamips VM instance name",
"type": "string", "type": "string",
"minLength": 1, "minLength": 1,
}, },
"router_id": {
"description": "VM/router instance ID",
"type": "integer"
},
"platform": { "platform": {
"description": "router platform", "description": "platform",
"type": "string", "type": "string",
"minLength": 1, "minLength": 1,
"pattern": "^c[0-9]{4}$" "pattern": "^c[0-9]{4}$"
}, },
"chassis": { "image": {
"description": "router chassis model", "description": "path to the IOS image",
"type": "string", "type": "string",
"minLength": 1, "minLength": 1,
"pattern": "^[0-9]{4}(XM)?$"
}, },
"image": { "startup_config": {
"description": "path to the IOS image file", "description": "path to the IOS startup configuration file",
"type": "string", "type": "string",
"minLength": 1 "minLength": 1,
},
"private_config": {
"description": "path to the IOS private configuration file",
"type": "string",
"minLength": 1,
}, },
"ram": { "ram": {
"description": "amount of RAM in MB", "description": "amount of RAM in MB",
"type": "integer" "type": "integer"
}, },
"nvram": {
"description": "amount of NVRAM in KB",
"type": "integer"
},
"mmap": {
"description": "MMAP feature",
"type": "boolean"
},
"sparsemem": {
"description": "sparse memory feature",
"type": "boolean"
},
"clock_divisor": {
"description": "clock divisor",
"type": "integer"
},
"idlepc": {
"description": "Idle-PC value",
"type": "string",
"pattern": "^(0x[0-9a-fA-F]+)?$"
},
"idlemax": {
"description": "idlemax value",
"type": "integer",
},
"idlesleep": {
"description": "idlesleep value",
"type": "integer",
},
"exec_area": {
"description": "exec area value",
"type": "integer",
},
"disk0": {
"description": "disk0 size in MB",
"type": "integer"
},
"disk1": {
"description": "disk1 size in MB",
"type": "integer"
},
"confreg": {
"description": "configuration register",
"type": "string",
"minLength": 1,
"pattern": "^0x[0-9a-fA-F]{4}$"
},
"console": { "console": {
"description": "console TCP port", "description": "console TCP port",
"type": "integer", "type": "integer",
@ -69,25 +130,352 @@ ROUTER_CREATE_SCHEMA = {
"minLength": 1, "minLength": 1,
"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$" "pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$"
}, },
"cloud_path": { "system_id": {
"description": "Path to the image in the cloud object store", "description": "system ID",
"type": "string", "type": "string",
} "minLength": 1,
},
"slot0": {
"description": "Network module slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot1": {
"description": "Network module slot 1",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot2": {
"description": "Network module slot 2",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot3": {
"description": "Network module slot 3",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot4": {
"description": "Network module slot 4",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot5": {
"description": "Network module slot 5",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot6": {
"description": "Network module slot 6",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic0": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic1": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic2": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"startup_config_base64": {
"description": "startup configuration base64 encoded",
"type": "string"
},
"private_config_base64": {
"description": "private configuration base64 encoded",
"type": "string"
},
# C7200 properties
"npe": {
"description": "NPE model",
"enum": ["npe-100",
"npe-150",
"npe-175",
"npe-200",
"npe-225",
"npe-300",
"npe-400",
"npe-g2"]
},
"midplane": {
"description": "Midplane model",
"enum": ["std", "vxr"]
},
"sensors": {
"description": "Temperature sensors",
"type": "array"
},
"power_supplies": {
"description": "Power supplies status",
"type": "array"
},
# I/O memory property for all platforms but C7200
"iomem": {
"description": "I/O memory percentage",
"type": "integer",
"minimum": 0,
"maximum": 100
},
}, },
"additionalProperties": False, "additionalProperties": False,
"required": ["name", "platform", "image", "ram"] "required": ["name", "platform", "image", "ram"]
} }
ROUTER_OBJECT_SCHEMA = { VM_UPDATE_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"description": "Dynamips router instance", "description": "Request validation to update a Dynamips VM instance",
"type": "object", "type": "object",
"properties": { "properties": {
"name": { "name": {
"description": "Dynamips router instance name", "description": "Dynamips VM instance name",
"type": "string", "type": "string",
"minLength": 1, "minLength": 1,
}, },
"platform": {
"description": "platform",
"type": "string",
"minLength": 1,
"pattern": "^c[0-9]{4}$"
},
"image": {
"description": "path to the IOS image",
"type": "string",
"minLength": 1,
},
"startup_config": {
"description": "path to the IOS startup configuration file",
"type": "string",
"minLength": 1,
},
"private_config": {
"description": "path to the IOS private configuration file",
"type": "string",
"minLength": 1,
},
"ram": {
"description": "amount of RAM in MB",
"type": "integer"
},
"nvram": {
"description": "amount of NVRAM in KB",
"type": "integer"
},
"mmap": {
"description": "MMAP feature",
"type": "boolean"
},
"sparsemem": {
"description": "sparse memory feature",
"type": "boolean"
},
"clock_divisor": {
"description": "clock divisor",
"type": "integer"
},
"idlepc": {
"description": "Idle-PC value",
"type": "string",
"pattern": "^(0x[0-9a-fA-F]+)?$"
},
"idlemax": {
"description": "idlemax value",
"type": "integer",
},
"idlesleep": {
"description": "idlesleep value",
"type": "integer",
},
"exec_area": {
"description": "exec area value",
"type": "integer",
},
"disk0": {
"description": "disk0 size in MB",
"type": "integer"
},
"disk1": {
"description": "disk1 size in MB",
"type": "integer"
},
"confreg": {
"description": "configuration register",
"type": "string",
"minLength": 1,
"pattern": "^0x[0-9a-fA-F]{4}$"
},
"console": {
"description": "console TCP port",
"type": "integer",
"minimum": 1,
"maximum": 65535
},
"aux": {
"description": "auxiliary console TCP port",
"type": "integer",
"minimum": 1,
"maximum": 65535
},
"mac_addr": {
"description": "base MAC address",
"type": "string",
"minLength": 1,
"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$"
},
"system_id": {
"description": "system ID",
"type": "string",
"minLength": 1,
},
"slot0": {
"description": "Network module slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot1": {
"description": "Network module slot 1",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot2": {
"description": "Network module slot 2",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot3": {
"description": "Network module slot 3",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot4": {
"description": "Network module slot 4",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot5": {
"description": "Network module slot 5",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot6": {
"description": "Network module slot 6",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic0": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic1": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic2": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"startup_config_base64": {
"description": "startup configuration base64 encoded",
"type": "string"
},
"private_config_base64": {
"description": "private configuration base64 encoded",
"type": "string"
},
# C7200 properties
"npe": {
"description": "NPE model",
"enum": ["npe-100",
"npe-150",
"npe-175",
"npe-200",
"npe-225",
"npe-300",
"npe-400",
"npe-g2"]
},
"midplane": {
"description": "Midplane model",
"enum": ["std", "vxr"]
},
"sensors": {
"description": "Temperature sensors",
"type": "array"
},
"power_supplies": {
"description": "Power supplies status",
"type": "array"
},
# I/O memory property for all platforms but C7200
"iomem": {
"description": "I/O memory percentage",
"type": "integer",
"minimum": 0,
"maximum": 100
},
},
"additionalProperties": False,
}
VM_OBJECT_SCHEMA = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Dynamips VM instance",
"type": "object",
"properties": {
"dynamips_id": {
"description": "ID to use with Dynamips",
"type": "integer"
},
"vm_id": { "vm_id": {
"description": "Dynamips router instance UUID", "description": "Dynamips router instance UUID",
"type": "string", "type": "string",
@ -102,7 +490,214 @@ ROUTER_OBJECT_SCHEMA = {
"maxLength": 36, "maxLength": 36,
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
}, },
"name": {
"description": "Dynamips VM instance name",
"type": "string",
"minLength": 1,
},
"platform": {
"description": "platform",
"type": "string",
"minLength": 1,
"pattern": "^c[0-9]{4}$"
},
"image": {
"description": "path to the IOS image",
"type": "string",
"minLength": 1,
},
"startup_config": {
"description": "path to the IOS startup configuration file",
"type": "string",
},
"private_config": {
"description": "path to the IOS private configuration file",
"type": "string",
},
"ram": {
"description": "amount of RAM in MB",
"type": "integer"
},
"nvram": {
"description": "amount of NVRAM in KB",
"type": "integer"
},
"mmap": {
"description": "MMAP feature",
"type": "boolean"
},
"sparsemem": {
"description": "sparse memory feature",
"type": "boolean"
},
"clock_divisor": {
"description": "clock divisor",
"type": "integer"
},
"idlepc": {
"description": "Idle-PC value",
"type": "string",
"pattern": "^(0x[0-9a-fA-F]+)?$"
},
"idlemax": {
"description": "idlemax value",
"type": "integer",
},
"idlesleep": {
"description": "idlesleep value",
"type": "integer",
},
"exec_area": {
"description": "exec area value",
"type": "integer",
},
"disk0": {
"description": "disk0 size in MB",
"type": "integer"
},
"disk1": {
"description": "disk1 size in MB",
"type": "integer"
},
"confreg": {
"description": "configuration register",
"type": "string",
"minLength": 1,
"pattern": "^0x[0-9a-fA-F]{4}$"
},
"console": {
"description": "console TCP port",
"type": "integer",
"minimum": 1,
"maximum": 65535
},
"aux": {
"description": "auxiliary console TCP port",
"type": "integer",
"minimum": 1,
"maximum": 65535
},
"mac_addr": {
"description": "base MAC address",
"type": "string",
#"minLength": 1,
#"pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$"
},
"system_id": {
"description": "system ID",
"type": "string",
"minLength": 1,
},
"slot0": {
"description": "Network module slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot1": {
"description": "Network module slot 1",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot2": {
"description": "Network module slot 2",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot3": {
"description": "Network module slot 3",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot4": {
"description": "Network module slot 4",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot5": {
"description": "Network module slot 5",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"slot6": {
"description": "Network module slot 6",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic0": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic1": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"wic2": {
"description": "Network module WIC slot 0",
"oneOf": [
{"type": "string"},
{"type": "null"}
]
},
"startup_config_base64": {
"description": "startup configuration base64 encoded",
"type": "string"
},
"private_config_base64": {
"description": "private configuration base64 encoded",
"type": "string"
},
# C7200 properties
"npe": {
"description": "NPE model",
"enum": ["npe-100",
"npe-150",
"npe-175",
"npe-200",
"npe-225",
"npe-300",
"npe-400",
"npe-g2"]
},
"midplane": {
"description": "Midplane model",
"enum": ["std", "vxr"]
},
"sensors": {
"description": "Temperature sensors",
"type": "array"
},
"power_supplies": {
"description": "Power supplies status",
"type": "array"
},
# I/O memory property for all platforms but C7200
"iomem": {
"description": "I/O memory percentage",
"type": "integer",
"minimum": 0,
"maximum": 100
},
}, },
"additionalProperties": False, "additionalProperties": False,
"required": ["name", "vm_id", "project_id"] "required": ["name", "vm_id", "project_id", "dynamips_id"]
} }

View File

@ -49,7 +49,7 @@ def _get_windows_interfaces_from_registry():
return interfaces return interfaces
def _get_windows_interfaces(): def get_windows_interfaces():
""" """
Get Windows interfaces. Get Windows interfaces.
@ -94,7 +94,7 @@ def interfaces():
return return
else: else:
try: try:
results = _get_windows_interfaces() results = get_windows_interfaces()
except ImportError: except ImportError:
message = "pywin32 module is not installed, please install it on the server to get the available interface names" message = "pywin32 module is not installed, please install it on the server to get the available interface names"
raise aiohttp.web.HTTPInternalServerError(text=message) raise aiohttp.web.HTTPInternalServerError(text=message)

View File

@ -1 +0,0 @@
/c3725.image

View File

@ -1,29 +0,0 @@
from gns3server.modules.dynamips import HypervisorManager
import pytest
import os
@pytest.fixture(scope="module")
def hypervisor(request):
dynamips_path = '/usr/bin/dynamips'
print("\nStarting Dynamips Hypervisor: {}".format(dynamips_path))
manager = HypervisorManager(dynamips_path, "/tmp", "127.0.0.1")
hypervisor = manager.start_new_hypervisor()
def stop():
print("\nStopping Dynamips Hypervisor")
manager.stop_all_hypervisors()
request.addfinalizer(stop)
return hypervisor
@pytest.fixture(scope="session")
def image(request):
cwd = os.path.dirname(os.path.abspath(__file__))
image_path = os.path.join(cwd, "c3725.image")
if not os.path.isfile(image_path):
return None
return image_path

Binary file not shown.

View File

@ -1,62 +0,0 @@
from gns3server.modules.dynamips import ATMBridge
from gns3server.modules.dynamips import NIO_Null
from gns3server.modules.dynamips import DynamipsError
import pytest
@pytest.fixture
def atm_bridge(request, hypervisor):
atm_bridge = ATMBridge(hypervisor, "ATM bridge")
request.addfinalizer(atm_bridge.delete)
return atm_bridge
def test_atm_bridge_exists(atm_bridge):
assert atm_bridge.list()
def test_rename_atm_bridge(atm_bridge):
atm_bridge.name = "new ATM bridge"
assert atm_bridge.name == "new ATM bridge"
def test_add_remove_nio(atm_bridge):
nio = NIO_Null(atm_bridge.hypervisor)
atm_bridge.add_nio(nio, 0) # add NIO on port 0
assert atm_bridge.nios
atm_bridge.remove_nio(0) # remove NIO from port 0
nio.delete()
def test_add_nio_already_allocated_port(atm_bridge):
nio = NIO_Null(atm_bridge.hypervisor)
atm_bridge.add_nio(nio, 0) # add NIO on port 0
with pytest.raises(DynamipsError):
atm_bridge.add_nio(nio, 0)
nio.delete()
def test_remove_nio_non_allocated_port(atm_bridge):
with pytest.raises(DynamipsError):
atm_bridge.remove_nio(0) # remove NIO from port 0
def test_bridge(atm_bridge):
nio1 = NIO_Null(atm_bridge.hypervisor)
atm_bridge.add_nio(nio1, 0) # add NIO on port 0 (Ethernet NIO)
nio2 = NIO_Null(atm_bridge.hypervisor)
atm_bridge.add_nio(nio1, 1) # add NIO on port 1 (ATM NIO)
atm_bridge.configure(0, 1, 10, 10) # configure Ethernet port 0 -> ATM port 1 with VC 10:10
assert atm_bridge.mapping[0] == (1, 10, 10)
atm_bridge.unconfigure()
atm_bridge.remove_nio(0)
atm_bridge.remove_nio(1)
nio1.delete()
nio2.delete()

View File

@ -1,83 +0,0 @@
from gns3server.modules.dynamips import ATMSwitch
from gns3server.modules.dynamips import NIO_Null
from gns3server.modules.dynamips import DynamipsError
import pytest
@pytest.fixture
def atmsw(request, hypervisor):
atmsw = ATMSwitch(hypervisor, "ATM switch")
request.addfinalizer(atmsw.delete)
return atmsw
def test_atmsw_exists(atmsw):
assert atmsw.list()
def test_rename_atmsw(atmsw):
atmsw.name = "new ATM switch"
assert atmsw.name == "new ATM switch"
def test_add_remove_nio(atmsw):
nio = NIO_Null(atmsw.hypervisor)
atmsw.add_nio(nio, 0) # add NIO on port 0
assert atmsw.nios
atmsw.remove_nio(0) # remove NIO from port 0
nio.delete()
def test_add_nio_already_allocated_port(atmsw):
nio = NIO_Null(atmsw.hypervisor)
atmsw.add_nio(nio, 0) # add NIO on port 0
with pytest.raises(DynamipsError):
atmsw.add_nio(nio, 0)
nio.delete()
def test_remove_nio_non_allocated_port(atmsw):
with pytest.raises(DynamipsError):
atmsw.remove_nio(0) # remove NIO from port 0
def test_vp(atmsw):
nio1 = NIO_Null(atmsw.hypervisor)
atmsw.add_nio(nio1, 0) # add NIO on port 0
nio2 = NIO_Null(atmsw.hypervisor)
atmsw.add_nio(nio1, 1) # add NIO on port 1
atmsw.map_vp(0, 10, 1, 20) # port 0 VP 10 to port 1 VP 20 (unidirectional)
atmsw.map_vp(1, 20, 0, 10) # port 1 VP 20 to port 0 VP 10 (unidirectional)
assert atmsw.mapping[(0, 10)] == (1, 20)
assert atmsw.mapping[(1, 20)] == (0, 10)
atmsw.unmap_vp(0, 10, 1, 20) # port 0 VP 10 to port 1 VP 20 (unidirectional)
atmsw.unmap_vp(1, 20, 0, 10) # port 1 VP 20 to port 0 VP 10 (unidirectional)
atmsw.remove_nio(0)
atmsw.remove_nio(1)
nio1.delete()
nio2.delete()
def test_pvc(atmsw):
nio1 = NIO_Null(atmsw.hypervisor)
atmsw.add_nio(nio1, 0) # add NIO on port 0
nio2 = NIO_Null(atmsw.hypervisor)
atmsw.add_nio(nio1, 1) # add NIO on port 1
atmsw.map_pvc(0, 10, 10, 1, 20, 20) # port 0 VC 10:10 to port 1 VP 20:20 (unidirectional)
atmsw.map_pvc(1, 20, 20, 0, 10, 10) # port 1 VC 20:20 to port 0 VC 10:10 (unidirectional)
assert atmsw.mapping[(0, 10, 10)] == (1, 20, 20)
assert atmsw.mapping[(1, 20, 20)] == (0, 10, 10)
atmsw.unmap_pvc(0, 10, 10, 1, 20, 20) # port 0 VC 10:10 to port 1 VP 20:20 (unidirectional)
atmsw.unmap_pvc(1, 20, 20, 0, 10, 10) # port 1 VC 20:20 to port 0 VC 10:10 (unidirectional)
atmsw.remove_nio(0)
atmsw.remove_nio(1)
nio1.delete()
nio2.delete()

View File

@ -1,31 +0,0 @@
from gns3server.modules.dynamips import Bridge
from gns3server.modules.dynamips import NIO_Null
import pytest
@pytest.fixture
def bridge(request, hypervisor):
bridge = Bridge(hypervisor, "bridge")
request.addfinalizer(bridge.delete)
return bridge
def test_bridge_exists(bridge):
assert bridge.list()
def test_rename_bridge(bridge):
bridge.name = "new bridge"
assert bridge.name == "new bridge"
def test_add_remove_nio(bridge):
nio = NIO_Null(bridge.hypervisor)
bridge.add_nio(nio)
assert bridge.nios
bridge.remove_nio(nio)
nio.delete()

View File

@ -1,167 +0,0 @@
from gns3server.modules.dynamips import C1700
from gns3server.modules.dynamips import DynamipsError
from gns3server.modules.dynamips import WIC_2T
from gns3server.modules.dynamips import WIC_1ENET
from gns3server.modules.dynamips import NIO_Null
import pytest
@pytest.fixture
def router_c1700(request, hypervisor):
router = C1700(hypervisor, "c1700 router")
request.addfinalizer(router.delete)
return router
def test_router_exists(router_c1700):
assert router_c1700.platform == "c1700"
assert router_c1700.list()
def test_chassis_1721(hypervisor):
router = C1700(hypervisor, "1721 chassis", chassis="1721")
assert router.chassis == "1721"
assert str(router.slots[0]) == "C1700-MB-1FE"
router.delete()
def test_chassis_change_to_1721(router_c1700):
assert router_c1700.chassis == "1720" # default chassis
router_c1700.chassis = "1721"
assert router_c1700.chassis == "1721"
def test_chassis_1750(hypervisor):
router = C1700(hypervisor, "1750 chassis", chassis="1750")
assert router.chassis == "1750"
assert str(router.slots[0]) == "C1700-MB-1FE"
router.delete()
def test_chassis_change_to_1750(router_c1700):
assert router_c1700.chassis == "1720" # default chassis
router_c1700.chassis = "1750"
assert router_c1700.chassis == "1750"
def test_chassis_1751(hypervisor):
router = C1700(hypervisor, "1751 chassis", chassis="1751")
assert router.chassis == "1751"
assert str(router.slots[0]) == "C1700-MB-1FE"
router.delete()
def test_chassis_change_to_1751(router_c1700):
assert router_c1700.chassis == "1720" # default chassis
router_c1700.chassis = "1751"
assert router_c1700.chassis == "1751"
def test_chassis_1760(hypervisor):
router = C1700(hypervisor, "1760 chassis", chassis="1760")
assert router.chassis == "1760"
assert str(router.slots[0]) == "C1700-MB-1FE"
router.delete()
def test_chassis_change_to_1760(router_c1700):
assert router_c1700.chassis == "1720" # default chassis
router_c1700.chassis = "1760"
assert router_c1700.chassis == "1760"
def test_iomem(router_c1700):
assert router_c1700.iomem == 15 # default value
router_c1700.iomem = 20
assert router_c1700.iomem == 20
def test_mac_addr(router_c1700):
assert router_c1700.mac_addr is not None
router_c1700.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router_c1700.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router_c1700):
with pytest.raises(DynamipsError):
router_c1700.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router_c1700):
assert router_c1700.system_id == "FTX0945W0MY" # default value
router_c1700.system_id = "FTX0945W0MO"
assert router_c1700.system_id == "FTX0945W0MO"
def test_get_hardware_info(router_c1700):
router_c1700.get_hardware_info() # FIXME: Dynamips doesn't return anything
def test_install_remove_wic(router_c1700):
wic = WIC_2T()
router_c1700.install_wic(0, wic) # install in WIC slot 0
assert router_c1700.slots[0].wics[0]
wic = WIC_1ENET()
router_c1700.install_wic(1, wic) # install in WIC slot 1
assert router_c1700.slots[0].wics[1]
router_c1700.uninstall_wic(0) # uninstall WIC from slot 0
assert not router_c1700.slots[0].wics[0]
def test_install_wic_into_wrong_slot(router_c1700):
wic = WIC_2T()
with pytest.raises(DynamipsError):
router_c1700.install_wic(2, wic) # install in WIC slot 2
def test_install_wic_into_already_occupied_slot(router_c1700):
wic = WIC_2T()
router_c1700.install_wic(0, wic) # install in WIC slot 0
wic = WIC_1ENET()
with pytest.raises(DynamipsError):
router_c1700.install_wic(0, wic) # install in WIC slot 0
def test_wic_add_remove_nio_binding(router_c1700):
nio = NIO_Null(router_c1700.hypervisor)
wic = WIC_2T()
router_c1700.install_wic(0, wic) # install WIC in slot 0
router_c1700.slot_add_nio_binding(0, 17, nio) # slot 0/17 (slot 0, wic 0, port 1)
assert router_c1700.slots[0].ports[17] == nio
assert router_c1700.get_slot_nio_bindings(slot_id=0)
router_c1700.slot_remove_nio_binding(0, 17) # slot 0/17 (slot 0, wic 0, port 1)
assert not router_c1700.get_slot_nio_bindings(slot_id=0)
assert not router_c1700.slots[0].ports[17] == nio
nio.delete()
def test_wic_add_remove_nio_binding_for_chassis_1760(hypervisor):
router = C1700(hypervisor, "1760 chassis", chassis="1760")
nio = NIO_Null(router.hypervisor)
wic = WIC_2T()
router.install_wic(1, wic) # install WIC in slot 1
router.slot_add_nio_binding(0, 32, nio) # slot 0/17 (slot 0, wic 1, port 0)
router.slot_remove_nio_binding(0, 32)
assert not router.get_slot_nio_bindings(slot_id=0)
nio.delete()
router.delete()

View File

@ -1,216 +0,0 @@
from gns3server.modules.dynamips import C2600
from gns3server.modules.dynamips import DynamipsError
from gns3server.modules.dynamips import NM_1E
from gns3server.modules.dynamips import NM_4E
from gns3server.modules.dynamips import NM_1FE_TX
from gns3server.modules.dynamips import NM_16ESW
import pytest
@pytest.fixture
def router_c2600(request, hypervisor):
router = C2600(hypervisor, "c2600 router")
request.addfinalizer(router.delete)
return router
def test_router_exists(router_c2600):
assert router_c2600.platform == "c2600"
assert router_c2600.list()
def test_chassis_2611(hypervisor):
router = C2600(hypervisor, "2611 chassis", chassis="2611")
assert router.chassis == "2611"
assert isinstance(router.slots[0], router.integrated_adapters["2611"])
router.delete()
def test_chassis_change_to_2611(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2611"
assert router_c2600.chassis == "2611"
def test_chassis_2620(hypervisor):
router = C2600(hypervisor, "2620 chassis", chassis="2620")
assert router.chassis == "2620"
assert isinstance(router.slots[0], router.integrated_adapters["2620"])
router.delete()
def test_chassis_change_to_2620(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2620"
assert router_c2600.chassis == "2620"
def test_chassis_2621(hypervisor):
router = C2600(hypervisor, "2621 chassis", chassis="2621")
assert router.chassis == "2621"
assert isinstance(router.slots[0], router.integrated_adapters["2621"])
router.delete()
def test_chassis_change_to_2621(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2621"
assert router_c2600.chassis == "2621"
def test_chassis_2610XM(hypervisor):
router = C2600(hypervisor, "2610XM chassis", chassis="2610XM")
assert router.chassis == "2610XM"
assert isinstance(router.slots[0], router.integrated_adapters["2610XM"])
router.delete()
def test_chassis_change_to_2610XM(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2610XM"
assert router_c2600.chassis == "2610XM"
def test_chassis_2611XM(hypervisor):
router = C2600(hypervisor, "2611XM chassis", chassis="2611XM")
assert router.chassis == "2611XM"
assert isinstance(router.slots[0], router.integrated_adapters["2611XM"])
router.delete()
def test_chassis_change_to_2611XM(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2611XM"
assert router_c2600.chassis == "2611XM"
def test_chassis_2620XM(hypervisor):
router = C2600(hypervisor, "2620XM chassis", chassis="2620XM")
assert router.chassis == "2620XM"
assert isinstance(router.slots[0], router.integrated_adapters["2620XM"])
router.delete()
def test_chassis_change_to_2620XM(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2620XM"
assert router_c2600.chassis == "2620XM"
def test_chassis_2621XM(hypervisor):
router = C2600(hypervisor, "2621XM chassis", chassis="2621XM")
assert router.chassis == "2621XM"
assert isinstance(router.slots[0], router.integrated_adapters["2621XM"])
router.delete()
def test_chassis_change_to_2621XM(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2621XM"
assert router_c2600.chassis == "2621XM"
def test_chassis_2650XM(hypervisor):
router = C2600(hypervisor, "2650XM chassis", chassis="2650XM")
assert router.chassis == "2650XM"
assert isinstance(router.slots[0], router.integrated_adapters["2650XM"])
router.delete()
def test_chassis_change_to_2650XM(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2650XM"
assert router_c2600.chassis == "2650XM"
def test_chassis_2651XM(hypervisor):
router = C2600(hypervisor, "2651XM chassis", chassis="2651XM")
assert router.chassis == "2651XM"
assert isinstance(router.slots[0], router.integrated_adapters["2651XM"])
router.delete()
def test_chassis_change_to_2651XM(router_c2600):
assert router_c2600.chassis == "2610" # default chassis
router_c2600.chassis = "2651XM"
assert router_c2600.chassis == "2651XM"
def test_iomem(router_c2600):
assert router_c2600.iomem == 15 # default value
router_c2600.iomem = 20
assert router_c2600.iomem == 20
def test_mac_addr(router_c2600):
assert router_c2600.mac_addr is not None
router_c2600.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router_c2600.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router_c2600):
with pytest.raises(DynamipsError):
router_c2600.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router_c2600):
assert router_c2600.system_id == "FTX0945W0MY" # default value
router_c2600.system_id = "FTX0945W0MO"
assert router_c2600.system_id == "FTX0945W0MO"
def test_get_hardware_info(router_c2600):
router_c2600.get_hardware_info() # FIXME: Dynamips doesn't return anything
def test_slot_add_NM_1E(router_c2600):
adapter = NM_1E()
router_c2600.slot_add_binding(1, adapter)
assert router_c2600.slots[1] == adapter
def test_slot_add_NM_4E(router_c2600):
adapter = NM_4E()
router_c2600.slot_add_binding(1, adapter)
assert router_c2600.slots[1] == adapter
def test_slot_add_NM_1FE_TX(router_c2600):
adapter = NM_1FE_TX()
router_c2600.slot_add_binding(1, adapter)
assert router_c2600.slots[1] == adapter
def test_slot_add_NM_16ESW(router_c2600):
adapter = NM_16ESW()
router_c2600.slot_add_binding(1, adapter)
assert router_c2600.slots[1] == adapter

View File

@ -1,73 +0,0 @@
from gns3server.modules.dynamips import C2691
from gns3server.modules.dynamips import DynamipsError
from gns3server.modules.dynamips import NM_1FE_TX
from gns3server.modules.dynamips import NM_4T
from gns3server.modules.dynamips import NM_16ESW
import pytest
@pytest.fixture
def router_c2691(request, hypervisor):
router = C2691(hypervisor, "c2691 router")
request.addfinalizer(router.delete)
return router
def test_router_exists(router_c2691):
assert router_c2691.platform == "c2691"
assert router_c2691.list()
def test_iomem(router_c2691):
assert router_c2691.iomem == 5 # default value
router_c2691.iomem = 10
assert router_c2691.iomem == 10
def test_mac_addr(router_c2691):
assert router_c2691.mac_addr is not None
router_c2691.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router_c2691.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router_c2691):
with pytest.raises(DynamipsError):
router_c2691.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router_c2691):
assert router_c2691.system_id == "FTX0945W0MY" # default value
router_c2691.system_id = "FTX0945W0MO"
assert router_c2691.system_id == "FTX0945W0MO"
def test_get_hardware_info(router_c2691):
router_c2691.get_hardware_info() # FIXME: Dynamips doesn't return anything
def test_slot_add_NM_1FE_TX(router_c2691):
adapter = NM_1FE_TX()
router_c2691.slot_add_binding(1, adapter)
assert router_c2691.slots[1] == adapter
def test_slot_add_NM_4T(router_c2691):
adapter = NM_4T()
router_c2691.slot_add_binding(1, adapter)
assert router_c2691.slots[1] == adapter
def test_slot_add_NM_16ESW(router_c2691):
adapter = NM_16ESW()
router_c2691.slot_add_binding(1, adapter)
assert router_c2691.slots[1] == adapter

View File

@ -1,118 +0,0 @@
from gns3server.modules.dynamips import C3600
from gns3server.modules.dynamips import DynamipsError
from gns3server.modules.dynamips import NM_1E
from gns3server.modules.dynamips import NM_4E
from gns3server.modules.dynamips import NM_1FE_TX
from gns3server.modules.dynamips import NM_16ESW
from gns3server.modules.dynamips import NM_4T
import pytest
@pytest.fixture
def router_c3600(request, hypervisor):
router = C3600(hypervisor, "c3600 router")
request.addfinalizer(router.delete)
return router
def test_router_exist(router_c3600):
assert router_c3600.platform == "c3600"
assert router_c3600.list()
def test_chassis_3620(hypervisor):
router = C3600(hypervisor, "3620 chassis", chassis="3620")
assert router.chassis == "3620"
router.delete()
def test_chassis_change_to_3620(router_c3600):
assert router_c3600.chassis == "3640" # default chassis
router_c3600.chassis = "3620"
assert router_c3600.chassis == "3620"
def test_chassis_3660(hypervisor):
router = C3600(hypervisor, "3660 chassis", chassis="3660")
assert router.chassis == "3660"
assert str(router.slots[0]) == "Leopard-2FE"
router.delete()
def test_chassis_change_to_3660(router_c3600):
assert router_c3600.chassis == "3640" # default chassis
router_c3600.chassis = "3660"
assert router_c3600.chassis == "3660"
def test_iomem(router_c3600):
assert router_c3600.iomem == 5 # default value
router_c3600.iomem = 10
assert router_c3600.iomem == 10
def test_mac_addr(router_c3600):
assert router_c3600.mac_addr is not None
router_c3600.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router_c3600.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router_c3600):
with pytest.raises(DynamipsError):
router_c3600.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router_c3600):
assert router_c3600.system_id == "FTX0945W0MY" # default value
router_c3600.system_id = "FTX0945W0MO"
assert router_c3600.system_id == "FTX0945W0MO"
def test_get_hardware_info(router_c3600):
router_c3600.get_hardware_info() # FIXME: Dynamips doesn't return anything
def test_slot_add_NM_1E(router_c3600):
adapter = NM_1E()
router_c3600.slot_add_binding(1, adapter)
assert router_c3600.slots[1] == adapter
def test_slot_add_NM_4E(router_c3600):
adapter = NM_4E()
router_c3600.slot_add_binding(1, adapter)
assert router_c3600.slots[1] == adapter
def test_slot_add_NM_1FE_TX(router_c3600):
adapter = NM_1FE_TX()
router_c3600.slot_add_binding(1, adapter)
assert router_c3600.slots[1] == adapter
def test_slot_add_NM_16ESW(router_c3600):
adapter = NM_16ESW()
router_c3600.slot_add_binding(1, adapter)
assert router_c3600.slots[1] == adapter
def test_slot_add_NM_4T(router_c3600):
adapter = NM_4T()
router_c3600.slot_add_binding(1, adapter)
assert router_c3600.slots[1] == adapter

View File

@ -1,73 +0,0 @@
from gns3server.modules.dynamips import C3725
from gns3server.modules.dynamips import DynamipsError
from gns3server.modules.dynamips import NM_1FE_TX
from gns3server.modules.dynamips import NM_4T
from gns3server.modules.dynamips import NM_16ESW
import pytest
@pytest.fixture
def router_c3725(request, hypervisor):
router = C3725(hypervisor, "c3725 router")
request.addfinalizer(router.delete)
return router
def test_router_exists(router_c3725):
assert router_c3725.platform == "c3725"
assert router_c3725.list()
def test_iomem(router_c3725):
assert router_c3725.iomem == 5 # default value
router_c3725.iomem = 10
assert router_c3725.iomem == 10
def test_mac_addr(router_c3725):
assert router_c3725.mac_addr is not None
router_c3725.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router_c3725.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router_c3725):
with pytest.raises(DynamipsError):
router_c3725.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router_c3725):
assert router_c3725.system_id == "FTX0945W0MY" # default value
router_c3725.system_id = "FTX0945W0MO"
assert router_c3725.system_id == "FTX0945W0MO"
def test_get_hardware_info(router_c3725):
router_c3725.get_hardware_info() # FIXME: Dynamips doesn't return anything
def test_slot_add_NM_1FE_TX(router_c3725):
adapter = NM_1FE_TX()
router_c3725.slot_add_binding(1, adapter)
assert router_c3725.slots[1] == adapter
def test_slot_add_NM_4T(router_c3725):
adapter = NM_4T()
router_c3725.slot_add_binding(1, adapter)
assert router_c3725.slots[1] == adapter
def test_slot_add_NM_16ESW(router_c3725):
adapter = NM_16ESW()
router_c3725.slot_add_binding(1, adapter)
assert router_c3725.slots[1] == adapter

View File

@ -1,73 +0,0 @@
from gns3server.modules.dynamips import C3745
from gns3server.modules.dynamips import DynamipsError
from gns3server.modules.dynamips import NM_1FE_TX
from gns3server.modules.dynamips import NM_4T
from gns3server.modules.dynamips import NM_16ESW
import pytest
@pytest.fixture
def router_c3745(request, hypervisor):
router = C3745(hypervisor, "c3745 router")
request.addfinalizer(router.delete)
return router
def test_router_exists(router_c3745):
assert router_c3745.platform == "c3745"
assert router_c3745.list()
def test_iomem(router_c3745):
assert router_c3745.iomem == 5 # default value
router_c3745.iomem = 10
assert router_c3745.iomem == 10
def test_mac_addr(router_c3745):
assert router_c3745.mac_addr is not None
router_c3745.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router_c3745.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router_c3745):
with pytest.raises(DynamipsError):
router_c3745.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router_c3745):
assert router_c3745.system_id == "FTX0945W0MY" # default value
router_c3745.system_id = "FTX0945W0MO"
assert router_c3745.system_id == "FTX0945W0MO"
def test_get_hardware_info(router_c3745):
router_c3745.get_hardware_info() # FIXME: Dynamips doesn't return anything
def test_slot_add_NM_1FE_TX(router_c3745):
adapter = NM_1FE_TX()
router_c3745.slot_add_binding(1, adapter)
assert router_c3745.slots[1] == adapter
def test_slot_add_NM_4T(router_c3745):
adapter = NM_4T()
router_c3745.slot_add_binding(1, adapter)
assert router_c3745.slots[1] == adapter
def test_slot_add_NM_16ESW(router_c3745):
adapter = NM_16ESW()
router_c3745.slot_add_binding(1, adapter)
assert router_c3745.slots[1] == adapter

View File

@ -1,188 +0,0 @@
from gns3server.modules.dynamips import C7200
from gns3server.modules.dynamips import DynamipsError
from gns3server.modules.dynamips import PA_2FE_TX
from gns3server.modules.dynamips import PA_4E
from gns3server.modules.dynamips import PA_4T
from gns3server.modules.dynamips import PA_8E
from gns3server.modules.dynamips import PA_8T
from gns3server.modules.dynamips import PA_A1
from gns3server.modules.dynamips import PA_FE_TX
from gns3server.modules.dynamips import PA_GE
from gns3server.modules.dynamips import PA_POS_OC3
from gns3server.modules.dynamips import NIO_Null
import pytest
@pytest.fixture
def router_c7200(request, hypervisor):
router = C7200(hypervisor, "c7200 router")
request.addfinalizer(router.delete)
return router
def test_router_exists(router_c7200):
assert router_c7200.platform == "c7200"
assert router_c7200.list()
def test_npe(router_c7200):
assert router_c7200.npe == "npe-400" # default value
router_c7200.npe = "npe-200"
assert router_c7200.npe == "npe-200"
def test_midplane(router_c7200):
assert router_c7200.midplane == "vxr" # default value
router_c7200.midplane = "std"
assert router_c7200.midplane == "std"
def test_sensors(router_c7200):
assert router_c7200.sensors == [22, 22, 22, 22] # default values (everything at 22C)
router_c7200.sensors = [25, 25, 25, 25]
assert router_c7200.sensors == [25, 25, 25, 25]
def test_power_supplies(router_c7200):
assert router_c7200.power_supplies == [1, 1] # default values (1 = powered on)
router_c7200.power_supplies = [0, 0]
assert router_c7200.power_supplies == [0, 0]
def test_mac_addr(router_c7200):
assert router_c7200.mac_addr is not None
router_c7200.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router_c7200.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router_c7200):
with pytest.raises(DynamipsError):
router_c7200.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router_c7200):
assert router_c7200.system_id == "FTX0945W0MY" # default value
router_c7200.system_id = "FTX0945W0MO"
assert router_c7200.system_id == "FTX0945W0MO"
def test_get_hardware_info(router_c7200):
router_c7200.get_hardware_info() # FIXME: Dynamips doesn't return anything
def test_slot_add_PA_2FE_TX(router_c7200):
adapter = PA_2FE_TX()
router_c7200.slot_add_binding(1, adapter)
assert router_c7200.slots[1] == adapter
def test_slot_add_PA_4E(router_c7200):
adapter = PA_4E()
router_c7200.slot_add_binding(2, adapter)
assert router_c7200.slots[2] == adapter
def test_slot_add_PA_4T(router_c7200):
adapter = PA_4T()
router_c7200.slot_add_binding(3, adapter)
assert router_c7200.slots[3] == adapter
def test_slot_add_PA_8E(router_c7200):
adapter = PA_8E()
router_c7200.slot_add_binding(4, adapter)
assert router_c7200.slots[4] == adapter
def test_slot_add_PA_8T(router_c7200):
adapter = PA_8T()
router_c7200.slot_add_binding(5, adapter)
assert router_c7200.slots[5] == adapter
def test_slot_add_PA_A1(router_c7200):
adapter = PA_A1()
router_c7200.slot_add_binding(1, adapter)
assert router_c7200.slots[1] == adapter
def test_slot_add_PA_FE_TX(router_c7200):
adapter = PA_FE_TX()
router_c7200.slot_add_binding(2, adapter)
assert router_c7200.slots[2] == adapter
def test_slot_add_PA_GE(router_c7200):
adapter = PA_GE()
router_c7200.slot_add_binding(3, adapter)
assert router_c7200.slots[3] == adapter
def test_slot_add_PA_POS_OC3(router_c7200):
adapter = PA_POS_OC3()
router_c7200.slot_add_binding(4, adapter)
assert router_c7200.slots[4] == adapter
def test_slot_add_into_already_occupied_slot(router_c7200):
adapter = PA_FE_TX()
with pytest.raises(DynamipsError):
router_c7200.slot_add_binding(0, adapter)
def test_slot_add_into_wrong_slot(router_c7200):
adapter = PA_FE_TX()
with pytest.raises(DynamipsError):
router_c7200.slot_add_binding(10, adapter)
def test_slot_remove_adapter(router_c7200):
adapter = PA_FE_TX()
router_c7200.slot_add_binding(1, adapter)
router_c7200.slot_remove_binding(1)
assert router_c7200.slots[1] is None
def test_slot_add_remove_nio_binding(router_c7200):
adapter = PA_FE_TX()
router_c7200.slot_add_binding(1, adapter)
nio = NIO_Null(router_c7200.hypervisor)
router_c7200.slot_add_nio_binding(1, 0, nio) # slot 1/0
assert router_c7200.get_slot_nio_bindings(slot_id=1)
assert router_c7200.slots[1].ports[0] == nio
router_c7200.slot_remove_nio_binding(1, 0) # slot 1/0
assert not router_c7200.get_slot_nio_bindings(slot_id=0)
nio.delete()
def test_slot_add_nio_to_wrong_port(router_c7200):
adapter = PA_FE_TX()
router_c7200.slot_add_binding(1, adapter)
nio = NIO_Null(router_c7200.hypervisor)
with pytest.raises(DynamipsError):
router_c7200.slot_add_nio_binding(1, 1, nio) # slot 1/1
nio.delete()

View File

@ -1,87 +0,0 @@
from gns3server.modules.dynamips import EthernetSwitch
from gns3server.modules.dynamips import NIO_Null
from gns3server.modules.dynamips import DynamipsError
import pytest
@pytest.fixture
def ethsw(request, hypervisor):
ethsw = EthernetSwitch(hypervisor, "Ethernet switch")
request.addfinalizer(ethsw.delete)
return ethsw
def test_ethsw_exists(ethsw):
assert ethsw.list()
def test_rename_ethsw(ethsw):
ethsw.name = "new Ethernet switch"
assert ethsw.name == "new Ethernet switch"
def test_add_remove_nio(ethsw):
nio = NIO_Null(ethsw.hypervisor)
ethsw.add_nio(nio, 0) # add NIO on port 0
assert ethsw.nios
ethsw.remove_nio(0) # remove NIO from port 0
nio.delete()
def test_add_nio_already_allocated_port(ethsw):
nio = NIO_Null(ethsw.hypervisor)
ethsw.add_nio(nio, 0) # add NIO on port 0
with pytest.raises(DynamipsError):
ethsw.add_nio(nio, 0)
nio.delete()
def test_remove_nio_non_allocated_port(ethsw):
with pytest.raises(DynamipsError):
ethsw.remove_nio(0) # remove NIO from port 0
def test_set_access_port(ethsw):
nio = NIO_Null(ethsw.hypervisor)
ethsw.add_nio(nio, 0) # add NIO on port 0
ethsw.set_access_port(0, 10) # set port 0 as access in VLAN 10
assert ethsw.mapping[0] == ("access", 10)
ethsw.remove_nio(0) # remove NIO from port 0
nio.delete()
def test_set_dot1q_port(ethsw):
nio = NIO_Null(ethsw.hypervisor)
ethsw.add_nio(nio, 0) # add NIO on port 0
ethsw.set_dot1q_port(0, 1) # set port 0 as 802.1Q trunk with native VLAN 1
assert ethsw.mapping[0] == ("dot1q", 1)
ethsw.remove_nio(0) # remove NIO from port 0
nio.delete()
def test_set_qinq_port(ethsw):
nio = NIO_Null(ethsw.hypervisor)
ethsw.add_nio(nio, 0) # add NIO on port 0
ethsw.set_qinq_port(0, 100) # set port 0 as QinQ trunk with outer VLAN 100
assert ethsw.mapping[0] == ("qinq", 100)
ethsw.remove_nio(0) # remove NIO from port 0
nio.delete()
def test_get_mac_addr_table(ethsw):
assert not ethsw.get_mac_addr_table() # MAC address table should be empty
def test_clear_mac_addr_table(ethsw):
ethsw.clear_mac_addr_table()

View File

@ -1,65 +0,0 @@
from gns3server.modules.dynamips import FrameRelaySwitch
from gns3server.modules.dynamips import NIO_Null
from gns3server.modules.dynamips import DynamipsError
import pytest
@pytest.fixture
def frsw(request, hypervisor):
frsw = FrameRelaySwitch(hypervisor, "Frane Relay switch")
request.addfinalizer(frsw.delete)
return frsw
def test_frsw_exists(frsw):
assert frsw.list()
def test_rename_frsw(frsw):
frsw.name = "new Frame Relay switch"
assert frsw.name == "new Frame Relay switch"
def test_add_remove_nio(frsw):
nio = NIO_Null(frsw.hypervisor)
frsw.add_nio(nio, 0) # add NIO on port 0
assert frsw.nios
frsw.remove_nio(0) # remove NIO from port 0
nio.delete()
def test_add_nio_already_allocated_port(frsw):
nio = NIO_Null(frsw.hypervisor)
frsw.add_nio(nio, 0) # add NIO on port 0
with pytest.raises(DynamipsError):
frsw.add_nio(nio, 0)
nio.delete()
def test_remove_nio_non_allocated_port(frsw):
with pytest.raises(DynamipsError):
frsw.remove_nio(0) # remove NIO from port 0
def test_vc(frsw):
nio1 = NIO_Null(frsw.hypervisor)
frsw.add_nio(nio1, 0) # add NIO on port 0
nio2 = NIO_Null(frsw.hypervisor)
frsw.add_nio(nio1, 1) # add NIO on port 1
frsw.map_vc(0, 10, 1, 20) # port 0 DLCI 10 to port 1 DLCI 20 (unidirectional)
frsw.map_vc(1, 20, 0, 10) # port 1 DLCI 20 to port 0 DLCI 10 (unidirectional)
assert frsw.mapping[(0, 10)] == (1, 20)
assert frsw.mapping[(1, 20)] == (0, 10)
frsw.unmap_vc(0, 10, 1, 20) # port 0 DLCI 10 to port 1 DLCI 20 (unidirectional)
frsw.unmap_vc(1, 20, 0, 10) # port 1 DLCI 20 to port 0 DLCI 10 (unidirectional)
frsw.remove_nio(0)
frsw.remove_nio(1)
nio1.delete()
nio2.delete()

View File

@ -1,25 +0,0 @@
from gns3server.modules.dynamips import Hub
from gns3server.modules.dynamips import NIO_Null
import pytest
@pytest.fixture
def hub(request, hypervisor):
hub = Hub(hypervisor, "hub")
request.addfinalizer(hub.delete)
return hub
def test_hub_exists(hub):
assert hub.list()
def test_add_remove_nio(hub):
nio = NIO_Null(hub.hypervisor)
hub.add_nio(nio, 0) # add NIO to port 0
assert hub.mapping[0] == nio
hub.remove_nio(0) # remove NIO from port 0
nio.delete()

View File

@ -1,41 +0,0 @@
from gns3server.modules.dynamips import Hypervisor
import time
def test_is_started(hypervisor):
assert hypervisor.is_running()
def test_port(hypervisor):
assert hypervisor.port == 7200
def test_host(hypervisor):
assert hypervisor.host == "0.0.0.0"
def test_working_dir(hypervisor):
assert hypervisor.working_dir == "/tmp"
def test_path(hypervisor):
dynamips_path = '/usr/bin/dynamips'
assert hypervisor.path == dynamips_path
def test_stdout():
# try to launch Dynamips on the same port
# this will fail so that we can read its stdout/stderr
dynamips_path = '/usr/bin/dynamips'
hypervisor = Hypervisor(dynamips_path, "/tmp", "127.0.0.1", 7200)
hypervisor.start()
# give some time for Dynamips to start
time.sleep(0.1)
output = hypervisor.read_stdout()
assert output

View File

@ -1,52 +0,0 @@
from gns3server.modules.dynamips import Router
from gns3server.modules.dynamips import HypervisorManager
import pytest
import os
@pytest.fixture(scope="module")
def hypervisor_manager(request):
dynamips_path = '/usr/bin/dynamips'
print("\nStarting Dynamips Hypervisor: {}".format(dynamips_path))
manager = HypervisorManager(dynamips_path, "/tmp", "127.0.0.1")
# manager.start_new_hypervisor()
def stop():
print("\nStopping Dynamips Hypervisor")
manager.stop_all_hypervisors()
request.addfinalizer(stop)
return manager
def test_allocate_hypervisor_for_router(hypervisor_manager):
hypervisor_manager.allocate_hypervisor_per_device = False
# default of 1GB of RAM per hypervisor instance
assert hypervisor_manager.memory_usage_limit_per_hypervisor == 1024
hypervisor = hypervisor_manager.allocate_hypervisor_for_router("c3725.image", 512)
assert hypervisor.is_running()
hypervisor = hypervisor_manager.allocate_hypervisor_for_router("c3725.image", 256)
assert hypervisor.memory_load == 768
hypervisor = hypervisor_manager.allocate_hypervisor_for_router("c3725.image", 512)
assert hypervisor.memory_load == 512
assert len(hypervisor_manager.hypervisors) == 2
def test_unallocate_hypervisor_for_router(hypervisor_manager):
assert len(hypervisor_manager.hypervisors) == 2
hypervisor = hypervisor_manager.hypervisors[0]
assert hypervisor.memory_load == 768
router = Router(hypervisor, "router", "c3725") # default is 128MB of RAM
hypervisor_manager.unallocate_hypervisor_for_router(router)
assert hypervisor.memory_load == 640
hypervisor.decrease_memory_load(512) # forces memory load down to 128
assert hypervisor.memory_load == 128
router.delete()
hypervisor_manager.unallocate_hypervisor_for_router(router)
# router is deleted and memory load to 0 now, one hypervisor must
# have been shutdown
assert len(hypervisor_manager.hypervisors) == 1

View File

@ -1,139 +0,0 @@
from gns3server.modules.dynamips import NIO_UDP
from gns3server.modules.dynamips import NIO_UDP_auto
from gns3server.modules.dynamips import NIO_FIFO
from gns3server.modules.dynamips import NIO_Mcast
from gns3server.modules.dynamips import NIO_Null
from gns3server.modules.dynamips import DynamipsError
import pytest
# TODO: test UNIX, TAP, VDE, generic Ethernet and Linux Ethernet NIOs
def test_nio_udp(hypervisor):
nio1 = NIO_UDP(hypervisor, 10001, "127.0.0.1", 10002)
assert nio1.lport == 10001
nio2 = NIO_UDP(hypervisor, 10002, "127.0.0.1", 10001)
assert nio2.lport == 10002
nio1.delete()
nio2.delete()
def test_nio_udp_auto(hypervisor):
nio1 = NIO_UDP_auto(hypervisor, "127.0.0.1", 10001, 10010)
assert nio1.lport == 10001
nio2 = NIO_UDP_auto(hypervisor, "127.0.0.1", 10001, 10010)
assert nio2.lport == 10002
nio1.connect("127.0.0.1", nio2.lport)
nio2.connect("127.0.0.1", nio1.lport)
nio1.delete()
nio2.delete()
def test_nio_fifo(hypervisor):
nio1 = NIO_FIFO(hypervisor)
nio2 = NIO_FIFO(hypervisor)
nio1.crossconnect(nio2)
assert nio1.list()
nio1.delete()
nio2.delete()
def test_nio_mcast(hypervisor):
nio1 = NIO_Mcast(hypervisor, "232.0.0.1", 10001)
assert nio1.group == "232.0.0.1"
assert nio1.port == 10001
nio1.ttl = 254
assert nio1.ttl == 254
nio2 = NIO_UDP(hypervisor, 10002, "232.0.0.1", 10001)
nio1.delete()
nio2.delete()
def test_nio_null(hypervisor):
nio = NIO_Null(hypervisor)
assert nio.list()
nio.delete()
def test_rename_nio(hypervisor):
nio = NIO_Null(hypervisor)
assert nio.name.startswith("nio_null")
nio.rename("test")
assert nio.name == "test"
nio.delete()
def test_debug_nio(hypervisor):
nio = NIO_Null(hypervisor)
nio.debug(1)
nio.debug(0)
nio.delete()
def test_bind_unbind_filter(hypervisor):
nio = NIO_Null(hypervisor)
nio.bind_filter("both", "freq_drop")
assert nio.input_filter == ("freq_drop", None)
assert nio.output_filter == ("freq_drop", None)
nio.unbind_filter("both")
nio.bind_filter("in", "capture")
assert nio.input_filter == ("capture", None)
nio.unbind_filter("in")
nio.delete()
def test_bind_unknown_filter(hypervisor):
nio = NIO_Null(hypervisor)
with pytest.raises(DynamipsError):
nio.bind_filter("both", "my_filter")
nio.delete()
def test_unbind_with_no_filter_applied(hypervisor):
nio = NIO_Null(hypervisor)
with pytest.raises(DynamipsError):
nio.unbind_filter("out")
nio.delete()
def test_setup_filter(hypervisor):
nio = NIO_Null(hypervisor)
nio.bind_filter("in", "freq_drop")
nio.setup_filter("in", "5") # drop every 5th packet
assert nio.input_filter == ("freq_drop", "5")
nio.unbind_filter("in")
nio.delete()
def test_get_stats(hypervisor):
nio = NIO_Null(hypervisor)
assert nio.get_stats() == "0 0 0 0" # nothing has been transmitted or received
nio.delete()
def test_reset_stats(hypervisor):
nio = NIO_Null(hypervisor)
nio.reset_stats()
nio.delete()
def test_set_bandwidth(hypervisor):
nio = NIO_Null(hypervisor)
assert nio.bandwidth is None # no constraint by default
nio.set_bandwidth(1000) # bandwidth = 1000 Kb/s
assert nio.bandwidth == 1000
nio.delete()

View File

@ -1,232 +0,0 @@
from gns3server.modules.dynamips import Router
from gns3server.modules.dynamips import DynamipsError
import sys
import pytest
import tempfile
import base64
@pytest.fixture
def router(request, hypervisor):
router = Router(hypervisor, "router", platform="c3725")
request.addfinalizer(router.delete)
return router
def test_hypervisor_is_started(hypervisor):
assert hypervisor.is_running()
def test_create_and_delete_router(hypervisor):
router = Router(hypervisor, "test my router")
assert router.id >= 0
assert router.name == "test my router"
assert router.platform == "c7200" # default platform
assert not router.is_running()
router.delete()
with pytest.raises(DynamipsError):
router.get_status()
def test_rename_router(hypervisor):
router = Router(hypervisor, "my router to rename")
assert router.name == "my router to rename"
router.name = "my_router"
assert router.name == "my_router"
router.delete()
def test_image(router):
# let's pretend this file is an IOS image
with tempfile.NamedTemporaryFile() as ios_image:
router.image = ios_image.name
assert router.image == ios_image.name
def test_set_config(router):
with tempfile.NamedTemporaryFile() as startup_config:
startup_config.write(b"hostname test_config\n")
router.set_config(startup_config.name)
def test_push_config(router):
startup_config = base64.b64encode(b"hostname test_config\n").decode("utf-8")
private_config = base64.b64encode(b"private config\n").decode("utf-8")
router.push_config(startup_config, private_config)
router_startup_config, router_private_config = router.extract_config()
assert startup_config == router_startup_config
assert private_config == router_private_config
def test_status(router, image):
# don't test if we have no IOS image
if not image:
return
assert router.get_status() == "inactive"
router.ram = 256
router.image = image
router.start()
assert router.is_running()
router.suspend()
assert router.get_status() == "suspended"
router.resume()
assert router.is_running()
router.stop()
assert router.get_status() == "inactive"
def test_ram(router):
assert router.ram == 128 # default ram
router.ram = 256
assert router.ram == 256
def test_nvram(router):
assert router.nvram == 128 # default nvram
router.nvram = 256
assert router.nvram == 256
def test_mmap(router):
assert router.mmap # default value
router.mmap = False
assert router.mmap == False
def test_sparsemem(router):
assert router.sparsemem # default value
router.sparsemem = False
assert router.sparsemem == False
def test_clock_divisor(router):
assert router.clock_divisor == 8 # default value
router.clock_divisor = 4
assert router.clock_divisor == 4
def test_idlepc(router):
assert router.idlepc == "" # no default value
router.idlepc = "0x60c086a8"
assert router.idlepc == "0x60c086a8"
def test_idlemax(router):
assert router.idlemax == 500 # default value
router.idlemax = 1500
assert router.idlemax == 1500
def test_idlesleep(router):
assert router.idlesleep == 30 # default value
router.idlesleep = 15
assert router.idlesleep == 15
def test_exec_area(router):
if sys.platform.startswith("win"):
assert router.exec_area == 16 # default value
else:
assert router.exec_area == 64 # default value
router.exec_area = 48
assert router.exec_area == 48
def test_disk0(router):
assert router.disk0 == 0 # default value
router.disk0 = 16
assert router.disk0 == 16
def test_disk1(router):
assert router.disk1 == 0 # default value
router.disk1 = 16
assert router.disk1 == 16
def test_confreg(router):
assert router.confreg == "0x2102" # default value
router.confreg = "0x2142"
assert router.confreg == "0x2142"
def test_console(router):
assert router.console == 2001
new_console_port = router.console + 100
router.console = new_console_port
assert router.console == new_console_port
def test_aux(router):
assert router.aux == 2501
new_aux_port = router.aux + 100
router.aux = new_aux_port
assert router.aux == new_aux_port
def test_cpu_info(router):
router.get_cpu_info() # nothing is returned by the hypervisor, cannot test?
def test_cpu_usage(router):
usage = router.get_cpu_usage()
assert usage == 0 # router isn't running, so usage must be 0
def test_get_slot_bindings(router):
assert router.get_slot_bindings()[0] == "0/0: GT96100-FE"
def test_get_slot_nio_bindings(router):
router.get_slot_nio_bindings(slot_id=0)
def test_mac_addr(router):
assert router.mac_addr is not None
router.mac_addr = "aa:aa:aa:aa:aa:aa"
assert router.mac_addr == "aa:aa:aa:aa:aa:aa"
def test_bogus_mac_addr(router):
with pytest.raises(DynamipsError):
router.mac_addr = "zz:zz:zz:zz:zz:zz"
def test_system_id(router):
assert router.system_id == "FTX0945W0MY" # default value
router.system_id = "FTX0945W0MO"
assert router.system_id == "FTX0945W0MO"
def test_get_hardware_info(router):
router.get_hardware_info()

View File

@ -1,65 +0,0 @@
from tornado.testing import AsyncHTTPTestCase
#from gns3server.plugins.dynamips import Dynamips
#from gns3server._compat import urlencode
from functools import partial
import tornado.web
import json
import tempfile
# class TestVMHandler(AsyncHTTPTestCase):
#
# def setUp(self):
#
# AsyncHTTPTestCase.setUp(self)
# self.post_request = partial(self.http_client.fetch,
# self.get_url("/api/vms/dynamips"),
# self.stop,
# method="POST")
#
# def get_app(self):
# return tornado.web.Application(Dynamips().handlers())
#
# def test_endpoint(self):
# self.http_client.fetch(self.get_url("/api/vms/dynamips"), self.stop)
# response = self.wait()
# assert response.code == 200
#
# def test_upload(self):
#
# try:
# from poster.encode import multipart_encode
# except ImportError:
# # poster isn't available for Python 3, let's just ignore the test
# return
#
# file_to_upload = tempfile.NamedTemporaryFile()
# data, headers = multipart_encode({"file1": file_to_upload})
# body = ""
# for d in data:
# body += d
#
# response = self.fetch('/api/vms/dynamips/storage/upload',
# headers=headers,
# body=body,
# method='POST')
#
# assert response.code == 200
#
# def get_new_ioloop(self):
# return tornado.ioloop.IOLoop.instance()
#
# def test_create_vm(self):
#
# post_data = {"name": "R1",
# "platform": "c3725",
# "console": 2000,
# "aux": 3000,
# "image": "c3725.bin",
# "ram": 128}
#
# self.post_request(body=json.dumps(post_data))
# response = self.wait()
# assert(response.headers['Content-Type'].startswith('application/json'))
# expected = {"success": True}
# assert response.body.decode("utf-8") == json.dumps(expected)

View File

@ -1,92 +0,0 @@
import uuid
from tornado.testing import AsyncTestCase
from tornado.escape import json_encode, json_decode
from ws4py.client.tornadoclient import TornadoWebSocketClient
import gns3server.jsonrpc as jsonrpc
"""
Tests for JSON-RPC protocol over Websockets
"""
class JSONRPC(AsyncTestCase):
URL = "ws://127.0.0.1:8000/"
def test_request(self):
params = {"echo": "test"}
request = jsonrpc.JSONRPCRequest("dynamips.echo", params)
AsyncWSRequest(self.URL, self.io_loop, self.stop, str(request))
response = self.wait()
json_response = json_decode(response)
assert json_response["jsonrpc"] == 2.0
assert json_response["id"] == request.id
assert json_response["result"] == params
def test_request_with_invalid_method(self):
message = {"echo": "test"}
request = jsonrpc.JSONRPCRequest("dynamips.non_existent", message)
AsyncWSRequest(self.URL, self.io_loop, self.stop, str(request))
response = self.wait()
json_response = json_decode(response)
assert json_response["error"].get("code") == -32601
assert json_response["id"] == request.id
def test_request_with_invalid_version(self):
request = {"jsonrpc": 1.0, "method": "dynamips.echo", "id": 1}
AsyncWSRequest(self.URL, self.io_loop, self.stop, json_encode(request))
response = self.wait()
json_response = json_decode(response)
assert json_response["id"] is None
assert json_response["error"].get("code") == -32600
def test_request_with_invalid_json(self):
request = "my non JSON request"
AsyncWSRequest(self.URL, self.io_loop, self.stop, request)
response = self.wait()
json_response = json_decode(response)
assert json_response["id"] is None
assert json_response["error"].get("code") == -32700
def test_request_with_invalid_jsonrpc_field(self):
request = {"jsonrpc": "2.0", "method_bogus": "dynamips.echo", "id": 1}
AsyncWSRequest(self.URL, self.io_loop, self.stop, json_encode(request))
response = self.wait()
json_response = json_decode(response)
assert json_response["id"] is None
assert json_response["error"].get("code") == -32700
def test_request_with_no_params(self):
request = jsonrpc.JSONRPCRequest("dynamips.echo")
AsyncWSRequest(self.URL, self.io_loop, self.stop, str(request))
response = self.wait()
json_response = json_decode(response)
assert json_response["id"] == request.id
assert json_response["error"].get("code") == -32602
class AsyncWSRequest(TornadoWebSocketClient):
"""
Very basic Websocket client for tests
"""
def __init__(self, url, io_loop, callback, message):
TornadoWebSocketClient.__init__(self, url, io_loop=io_loop)
self._callback = callback
self._message = message
self.connect()
def opened(self):
self.send(self._message, binary=False)
def received_message(self, message):
self.close()
if self._callback:
self._callback(message.data)

125
tests/api/test_dynamips.py Normal file
View File

@ -0,0 +1,125 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from tests.utils import asyncio_patch
# @pytest.yield_fixture(scope="module")
# def vm(server, project):
#
# dynamips_path = "/fake/dynamips"
# with asyncio_patch("gns3server.modules.dynamips.nodes.router.Router.create", return_value=True) as mock:
# response = server.post("/projects/{project_id}/dynamips/vms".format(project_id=project.id), {"name": "My router",
# "platform": "c3745",
# "image": "somewhere",
# "ram": 128})
# assert mock.called
# assert response.status == 201
#
# with asyncio_patch("gns3server.modules.dynamips.Dynamips.find_dynamips", return_value=dynamips_path):
# yield response.json
#
#
# def test_dynamips_vm_create(server, project):
#
# with asyncio_patch("gns3server.modules.dynamips.nodes.router.Router.create", return_value=True):
# response = server.post("/projects/{project_id}/dynamips/vms".format(project_id=project.id), {"name": "My router",
# "platform": "c3745",
# "image": "somewhere",
# "ram": 128},
# example=True)
# assert response.status == 201
# assert response.json["name"] == "My router"
# assert response.json["project_id"] == project.id
# assert response.json["dynamips_id"]
#
#
# def test_dynamips_vm_get(server, project, vm):
# response = server.get("/projects/{project_id}/dynamips/vms/{vm_id}".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), example=True)
# assert response.status == 200
# assert response.route == "/projects/{project_id}/dynamips/vms/{vm_id}"
# assert response.json["name"] == "My router"
# assert response.json["project_id"] == project.id
#
#
# def test_dynamips_vm_start(server, vm):
# with asyncio_patch("gns3server.modules.dynamips.nodes.router.Router.start", return_value=True) as mock:
# response = server.post("/projects/{project_id}/dynamips/vms/{vm_id}/start".format(project_id=vm["project_id"], vm_id=vm["vm_id"]))
# assert mock.called
# assert response.status == 204
#
#
# def test_dynamips_vm_stop(server, vm):
# with asyncio_patch("gns3server.modules.dynamips.nodes.router.Router.stop", return_value=True) as mock:
# response = server.post("/projects/{project_id}/dynamips/vms/{vm_id}/stop".format(project_id=vm["project_id"], vm_id=vm["vm_id"]))
# assert mock.called
# assert response.status == 204
#
#
# def test_dynamips_vm_suspend(server, vm):
# with asyncio_patch("gns3server.modules.dynamips.nodes.router.Router.suspend", return_value=True) as mock:
# response = server.post("/projects/{project_id}/dynamips/vms/{vm_id}/suspend".format(project_id=vm["project_id"], vm_id=vm["vm_id"]))
# assert mock.called
# assert response.status == 204
#
#
# def test_dynamips_vm_resume(server, vm):
# with asyncio_patch("gns3server.modules.dynamips.nodes.router.Router.resume", return_value=True) as mock:
# response = server.post("/projects/{project_id}/dynamips/vms/{vm_id}/resume".format(project_id=vm["project_id"], vm_id=vm["vm_id"]))
# assert mock.called
# assert response.status == 204
# def test_vbox_nio_create_udp(server, vm):
#
# with asyncio_patch('gns3server.modules.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_add_nio_binding') as mock:
# response = server.post("/projects/{project_id}/virtualbox/vms/{vm_id}/adapters/0/nio".format(project_id=vm["project_id"],
# vm_id=vm["vm_id"]), {"type": "nio_udp",
# "lport": 4242,
# "rport": 4343,
# "rhost": "127.0.0.1"},
# example=True)
#
# assert mock.called
# args, kwgars = mock.call_args
# assert args[0] == 0
#
# assert response.status == 201
# assert response.route == "/projects/{project_id}/virtualbox/vms/{vm_id}/adapters/{adapter_id:\d+}/nio"
# assert response.json["type"] == "nio_udp"
#
#
# def test_vbox_delete_nio(server, vm):
#
# with asyncio_patch('gns3server.modules.virtualbox.virtualbox_vm.VirtualBoxVM.adapter_remove_nio_binding') as mock:
# response = server.delete("/projects/{project_id}/virtualbox/vms/{vm_id}/adapters/0/nio".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), example=True)
#
# assert mock.called
# args, kwgars = mock.call_args
# assert args[0] == 0
#
# assert response.status == 204
# assert response.route == "/projects/{project_id}/virtualbox/vms/{vm_id}/adapters/{adapter_id:\d+}/nio"
#
#
# def test_vbox_update(server, vm, free_console_port):
# response = server.put("/projects/{project_id}/virtualbox/vms/{vm_id}".format(project_id=vm["project_id"], vm_id=vm["vm_id"]), {"name": "test",
# "console": free_console_port})
# assert response.status == 200
# assert response.json["name"] == "test"
# assert response.json["console"] == free_console_port

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import tempfile
from gns3server.modules.dynamips import Dynamips
from gns3server.modules.dynamips.dynamips_error import DynamipsError
from unittest.mock import patch
@pytest.fixture(scope="module")
def manager(port_manager):
m = Dynamips.instance()
m.port_manager = port_manager
return m
def test_vm_invalid_dynamips_path(manager):
with patch("gns3server.config.Config.get_section_config", return_value={"dynamips_path": "/bin/test_fake"}):
with pytest.raises(DynamipsError):
manager.find_dynamips()
def test_vm_non_executable_dynamips_path(manager):
tmpfile = tempfile.NamedTemporaryFile()
with patch("gns3server.config.Config.get_section_config", return_value={"dynamips_path": tmpfile.name}):
with pytest.raises(DynamipsError):
manager.find_dynamips()

View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
import asyncio
from unittest.mock import patch
from gns3server.modules.dynamips.nodes.router import Router
from gns3server.modules.dynamips.dynamips_error import DynamipsError
from gns3server.modules.dynamips import Dynamips
@pytest.fixture(scope="module")
def manager(port_manager):
m = Dynamips.instance()
m.port_manager = port_manager
return m
@pytest.fixture(scope="function")
def router(project, manager):
return Router("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
def test_router(project, manager):
router = Router("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
assert router.name == "test"
assert router.id == "00010203-0405-0607-0809-0a0b0c0d0e0f"
def test_router_invalid_dynamips_path(project, manager, loop):
with patch("gns3server.config.Config.get_section_config", return_value={"dynamips_path": "/bin/test_fake"}):
with pytest.raises(DynamipsError):
router = Router("test", "00010203-0405-0607-0809-0a0b0c0d0e0e", project, manager)
loop.run_until_complete(asyncio.async(router.create()))
assert router.name == "test"
assert router.id == "00010203-0405-0607-0809-0a0b0c0d0e0e"

View File

@ -31,13 +31,13 @@ def manager(port_manager):
return m return m
@patch("gns3server.config.Config.get_section_config", return_value={"vboxmanage_path": "/bin/test_fake"}) def test_vm_invalid_vboxmanage_path(manager):
def test_vm_invalid_vboxmanage_path(project, manager): with patch("gns3server.config.Config.get_section_config", return_value={"vboxmanage_path": "/bin/test_fake"}):
with pytest.raises(VirtualBoxError): with pytest.raises(VirtualBoxError):
manager.find_vboxmanage() manager.find_vboxmanage()
def test_vm_non_executable_vboxmanage_path(project, manager): def test_vm_non_executable_vboxmanage_path(manager):
tmpfile = tempfile.NamedTemporaryFile() tmpfile = tempfile.NamedTemporaryFile()
with patch("gns3server.config.Config.get_section_config", return_value={"vboxmanage_path": tmpfile.name}): with patch("gns3server.config.Config.get_section_config", return_value={"vboxmanage_path": tmpfile.name}):
with pytest.raises(VirtualBoxError): with pytest.raises(VirtualBoxError):