diff --git a/gns3server/config.py b/gns3server/config.py index 21e1e5b9..05c0cb96 100644 --- a/gns3server/config.py +++ b/gns3server/config.py @@ -186,7 +186,7 @@ class Config(object): """ 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 """ diff --git a/gns3server/handlers/dynamips_handler.py b/gns3server/handlers/dynamips_handler.py index 85d79cf6..0b0be6a1 100644 --- a/gns3server/handlers/dynamips_handler.py +++ b/gns3server/handlers/dynamips_handler.py @@ -15,10 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os + +import asyncio from ..web.route import Route -from ..schemas.dynamips import ROUTER_CREATE_SCHEMA -from ..schemas.dynamips import ROUTER_OBJECT_SCHEMA +from ..schemas.dynamips import VM_CREATE_SCHEMA +from ..schemas.dynamips import VM_UPDATE_SCHEMA +from ..schemas.dynamips import VM_OBJECT_SCHEMA from ..modules.dynamips import Dynamips from ..modules.project_manager import ProjectManager @@ -31,7 +33,7 @@ class DynamipsHandler: @classmethod @Route.post( - r"/projects/{project_id}/dynamips/routers", + r"/projects/{project_id}/dynamips/vms", parameters={ "project_id": "UUID for the project" }, @@ -40,20 +42,194 @@ class DynamipsHandler: 400: "Invalid request", 409: "Conflict" }, - description="Create a new Dynamips router instance", - input=ROUTER_CREATE_SCHEMA) - #output=ROUTER_OBJECT_SCHEMA) + description="Create a new Dynamips VM instance", + input=VM_CREATE_SCHEMA, + output=VM_OBJECT_SCHEMA) def create(request, response): dynamips_manager = Dynamips.instance() vm = yield from dynamips_manager.create_vm(request.json.pop("name"), request.match_info["project_id"], request.json.get("vm_id"), + request.json.get("dynamips_id"), request.json.pop("platform")) - #for name, value in request.json.items(): - # if hasattr(vm, name) and getattr(vm, name) != value: - # setattr(vm, name, value) + # set VM options + for name, value in request.json.items(): + 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.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) diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index 4b401384..1edc2a39 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -19,81 +19,18 @@ Dynamips server module. """ +import aiohttp import sys import os -import base64 -import tempfile import shutil -import glob 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 asyncio import logging log = logging.getLogger(__name__) +from gns3server.utils.interfaces import get_windows_interfaces from pkg_resources import parse_version from ..base_manager import BaseManager from .dynamips_error import DynamipsError @@ -101,6 +38,18 @@ from .hypervisor import Hypervisor from .nodes.router import Router 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): @@ -113,7 +62,35 @@ class Dynamips(BaseManager): # FIXME: temporary 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): @@ -168,6 +145,9 @@ class Dynamips(BaseManager): :returns: the new hypervisor instance """ + if not self._dynamips_path: + self.find_dynamips() + try: # let the OS find an unused port for the Dynamips hypervisor with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: @@ -190,323 +170,97 @@ class Dynamips(BaseManager): 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): # """ # Manages Ghost IOS support. diff --git a/gns3server/modules/dynamips/dynamips_hypervisor.py b/gns3server/modules/dynamips/dynamips_hypervisor.py index 954d6d4b..9a1fb6f4 100644 --- a/gns3server/modules/dynamips/dynamips_hypervisor.py +++ b/gns3server/modules/dynamips/dynamips_hypervisor.py @@ -26,7 +26,7 @@ import logging import asyncio 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__) @@ -415,7 +415,7 @@ class DynamipsHypervisor: """ # 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 allocated_port = nio.lport return allocated_port diff --git a/gns3server/modules/dynamips/dynamips_vm.py b/gns3server/modules/dynamips/dynamips_vm.py index 3beed541..b73b1dbf 100644 --- a/gns3server/modules/dynamips/dynamips_vm.py +++ b/gns3server/modules/dynamips/dynamips_vm.py @@ -42,9 +42,9 @@ class DynamipsVM: 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: 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) diff --git a/gns3server/modules/dynamips/nios/nio_fifo.py b/gns3server/modules/dynamips/nios/nio_fifo.py index 768d87af..60c9aa3f 100644 --- a/gns3server/modules/dynamips/nios/nio_fifo.py +++ b/gns3server/modules/dynamips/nios/nio_fifo.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_FIFO(NIO): +class NIOFIFO(NIO): """ Dynamips FIFO NIO. @@ -40,8 +40,8 @@ class NIO_FIFO(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_FIFO._instance_count - NIO_FIFO._instance_count += 1 + self._id = NIOFIFO._instance_count + NIOFIFO._instance_count += 1 self._name = 'nio_fifo' + str(self._id) @classmethod diff --git a/gns3server/modules/dynamips/nios/nio_generic_ethernet.py b/gns3server/modules/dynamips/nios/nio_generic_ethernet.py index 4428e2bf..fc0ab006 100644 --- a/gns3server/modules/dynamips/nios/nio_generic_ethernet.py +++ b/gns3server/modules/dynamips/nios/nio_generic_ethernet.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_GenericEthernet(NIO): +class NIOGenericEthernet(NIO): """ Dynamips generic Ethernet NIO. @@ -41,8 +41,8 @@ class NIO_GenericEthernet(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_GenericEthernet._instance_count - NIO_GenericEthernet._instance_count += 1 + self._id = NIOGenericEthernet._instance_count + NIOGenericEthernet._instance_count += 1 self._name = 'nio_gen_eth' + str(self._id) self._ethernet_device = ethernet_device diff --git a/gns3server/modules/dynamips/nios/nio_linux_ethernet.py b/gns3server/modules/dynamips/nios/nio_linux_ethernet.py index 28bfbe89..513bc12a 100644 --- a/gns3server/modules/dynamips/nios/nio_linux_ethernet.py +++ b/gns3server/modules/dynamips/nios/nio_linux_ethernet.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_LinuxEthernet(NIO): +class NIOLinuxEthernet(NIO): """ Dynamips Linux Ethernet NIO. @@ -41,8 +41,8 @@ class NIO_LinuxEthernet(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_LinuxEthernet._instance_count - NIO_LinuxEthernet._instance_count += 1 + self._id = NIOLinuxEthernet._instance_count + NIOLinuxEthernet._instance_count += 1 self._name = 'nio_linux_eth' + str(self._id) self._ethernet_device = ethernet_device diff --git a/gns3server/modules/dynamips/nios/nio_mcast.py b/gns3server/modules/dynamips/nios/nio_mcast.py index fe32135b..cf03aaab 100644 --- a/gns3server/modules/dynamips/nios/nio_mcast.py +++ b/gns3server/modules/dynamips/nios/nio_mcast.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_Mcast(NIO): +class NIOMcast(NIO): """ Dynamips Linux Ethernet NIO. @@ -42,8 +42,8 @@ class NIO_Mcast(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_Mcast._instance_count - NIO_Mcast._instance_count += 1 + self._id = NIOMcast._instance_count + NIOMcast._instance_count += 1 self._name = 'nio_mcast' + str(self._id) self._group = group self._port = port diff --git a/gns3server/modules/dynamips/nios/nio_null.py b/gns3server/modules/dynamips/nios/nio_null.py index b8113e59..df666fb8 100644 --- a/gns3server/modules/dynamips/nios/nio_null.py +++ b/gns3server/modules/dynamips/nios/nio_null.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_Null(NIO): +class NIONull(NIO): """ Dynamips NULL NIO. @@ -40,8 +40,8 @@ class NIO_Null(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_Null._instance_count - NIO_Null._instance_count += 1 + self._id = NIONull._instance_count + NIONull._instance_count += 1 self._name = 'nio_null' + str(self._id) @classmethod diff --git a/gns3server/modules/dynamips/nios/nio_tap.py b/gns3server/modules/dynamips/nios/nio_tap.py index efe47a9e..926e9b0b 100644 --- a/gns3server/modules/dynamips/nios/nio_tap.py +++ b/gns3server/modules/dynamips/nios/nio_tap.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_TAP(NIO): +class NIOTAP(NIO): """ Dynamips TAP NIO. @@ -41,8 +41,8 @@ class NIO_TAP(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_TAP._instance_count - NIO_TAP._instance_count += 1 + self._id = NIOTAP._instance_count + NIOTAP._instance_count += 1 self._name = 'nio_tap' + str(self._id) self._tap_device = tap_device diff --git a/gns3server/modules/dynamips/nios/nio_udp.py b/gns3server/modules/dynamips/nios/nio_udp.py index 0bae8bbf..999fdf9a 100644 --- a/gns3server/modules/dynamips/nios/nio_udp.py +++ b/gns3server/modules/dynamips/nios/nio_udp.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_UDP(NIO): +class NIOUDP(NIO): """ Dynamips UDP NIO. @@ -43,8 +43,8 @@ class NIO_UDP(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_UDP._instance_count - NIO_UDP._instance_count += 1 + self._id = NIOUDP._instance_count + NIOUDP._instance_count += 1 self._name = 'nio_udp' + str(self._id) self._lport = lport self._rhost = rhost diff --git a/gns3server/modules/dynamips/nios/nio_udp_auto.py b/gns3server/modules/dynamips/nios/nio_udp_auto.py index eb42e580..1caaaea0 100644 --- a/gns3server/modules/dynamips/nios/nio_udp_auto.py +++ b/gns3server/modules/dynamips/nios/nio_udp_auto.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_UDP_auto(NIO): +class NIOUDPAuto(NIO): """ Dynamips auto UDP NIO. @@ -43,8 +43,8 @@ class NIO_UDP_auto(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_UDP_auto._instance_count - NIO_UDP_auto._instance_count += 1 + self._id = NIOUDPAuto._instance_count + NIOUDPAuto._instance_count += 1 self._name = 'nio_udp_auto' + str(self._id) self._laddr = laddr diff --git a/gns3server/modules/dynamips/nios/nio_unix.py b/gns3server/modules/dynamips/nios/nio_unix.py index af913f88..234fd65b 100644 --- a/gns3server/modules/dynamips/nios/nio_unix.py +++ b/gns3server/modules/dynamips/nios/nio_unix.py @@ -26,7 +26,7 @@ import logging log = logging.getLogger(__name__) -class NIO_UNIX(NIO): +class NIOUNIX(NIO): """ Dynamips UNIX NIO. @@ -42,8 +42,8 @@ class NIO_UNIX(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_UNIX._instance_count - NIO_UNIX._instance_count += 1 + self._id = NIOUNIX._instance_count + NIOUNIX._instance_count += 1 self._name = 'nio_unix' + str(self._id) self._local_file = local_file self._remote_file = remote_file diff --git a/gns3server/modules/dynamips/nios/nio_vde.py b/gns3server/modules/dynamips/nios/nio_vde.py index 79af96d7..6b00cf2f 100644 --- a/gns3server/modules/dynamips/nios/nio_vde.py +++ b/gns3server/modules/dynamips/nios/nio_vde.py @@ -25,7 +25,7 @@ import logging log = logging.getLogger(__name__) -class NIO_VDE(NIO): +class NIOVDE(NIO): """ Dynamips VDE NIO. @@ -41,8 +41,8 @@ class NIO_VDE(NIO): NIO.__init__(self, hypervisor) # create an unique ID - self._id = NIO_VDE._instance_count - NIO_VDE._instance_count += 1 + self._id = NIOVDE._instance_count + NIOVDE._instance_count += 1 self._name = 'nio_vde' + str(self._id) self._control_file = control_file self._local_file = local_file diff --git a/gns3server/modules/dynamips/nodes/c1700.py b/gns3server/modules/dynamips/nodes/c1700.py index 6bfe30e0..faee65cd 100644 --- a/gns3server/modules/dynamips/nodes/c1700.py +++ b/gns3server/modules/dynamips/nodes/c1700.py @@ -37,13 +37,14 @@ class C1700(Router): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips :param chassis: chassis for this router: 1720, 1721, 1750, 1751 or 1760 (default = 1720). 1710 is not supported. """ - def __init__(self, name, vm_id, project, manager, chassis="1720"): - Router.__init__(self, name, vm_id, project, manager, platform="c1700") + def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="1720"): + Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c1700") # Set default values for this platform self._ram = 128 diff --git a/gns3server/modules/dynamips/nodes/c2600.py b/gns3server/modules/dynamips/nodes/c2600.py index 6f53ad14..e3972253 100644 --- a/gns3server/modules/dynamips/nodes/c2600.py +++ b/gns3server/modules/dynamips/nodes/c2600.py @@ -39,6 +39,7 @@ class C2600(Router): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips :param chassis: chassis for this router: 2610, 2611, 2620, 2621, 2610XM, 2611XM 2620XM, 2621XM, 2650XM or 2651XM (default = 2610). @@ -57,8 +58,8 @@ class C2600(Router): "2650XM": C2600_MB_1FE, "2651XM": C2600_MB_2FE} - def __init__(self, name, vm_id, project, manager, chassis="2610"): - Router.__init__(self, name, vm_id, project, manager, platform="c2600") + def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="2610"): + Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c2600") # Set default values for this platform self._ram = 128 diff --git a/gns3server/modules/dynamips/nodes/c2691.py b/gns3server/modules/dynamips/nodes/c2691.py index 60489405..273b33de 100644 --- a/gns3server/modules/dynamips/nodes/c2691.py +++ b/gns3server/modules/dynamips/nodes/c2691.py @@ -36,10 +36,11 @@ class C2691(Router): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips """ - def __init__(self, name, vm_id, project, manager): - Router.__init__(self, name, vm_id, project, manager, platform="c2691") + def __init__(self, name, vm_id, project, manager, dynamips_id): + Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c2691") # Set default values for this platform self._ram = 192 diff --git a/gns3server/modules/dynamips/nodes/c3600.py b/gns3server/modules/dynamips/nodes/c3600.py index 42e2ea79..fe11b48d 100644 --- a/gns3server/modules/dynamips/nodes/c3600.py +++ b/gns3server/modules/dynamips/nodes/c3600.py @@ -36,12 +36,13 @@ class C3600(Router): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips :param chassis: chassis for this router: 3620, 3640 or 3660 (default = 3640). """ - def __init__(self, name, vm_id, project, manager, chassis="3640"): - Router.__init__(self, name, vm_id, project, manager, platform="c3600") + def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="3640"): + Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3600") # Set default values for this platform self._ram = 192 diff --git a/gns3server/modules/dynamips/nodes/c3725.py b/gns3server/modules/dynamips/nodes/c3725.py index cad3716f..6cb4213c 100644 --- a/gns3server/modules/dynamips/nodes/c3725.py +++ b/gns3server/modules/dynamips/nodes/c3725.py @@ -36,10 +36,11 @@ class C3725(Router): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips """ - def __init__(self, name, vm_id, project, manager): - Router.__init__(self, name, vm_id, project, manager, platform="c3725") + def __init__(self, name, vm_id, project, manager, dynamips_id): + Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3725") # Set default values for this platform self._ram = 128 diff --git a/gns3server/modules/dynamips/nodes/c3745.py b/gns3server/modules/dynamips/nodes/c3745.py index 5ef49d11..28acfe99 100644 --- a/gns3server/modules/dynamips/nodes/c3745.py +++ b/gns3server/modules/dynamips/nodes/c3745.py @@ -36,10 +36,11 @@ class C3745(Router): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips """ - def __init__(self, name, vm_id, project, manager): - Router.__init__(self, name, vm_id, project, manager, platform="c3745") + def __init__(self, name, vm_id, project, manager, dynamips_id): + Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3745") # Set default values for this platform self._ram = 256 diff --git a/gns3server/modules/dynamips/nodes/c7200.py b/gns3server/modules/dynamips/nodes/c7200.py index 777907bc..4d69e825 100644 --- a/gns3server/modules/dynamips/nodes/c7200.py +++ b/gns3server/modules/dynamips/nodes/c7200.py @@ -39,11 +39,12 @@ class C7200(Router): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips :param npe: Default NPE """ - def __init__(self, name, vm_id, project, manager, npe="npe-400"): - Router.__init__(self, name, vm_id, project, manager, platform="c7200") + def __init__(self, name, vm_id, project, manager, dynamips_id, npe="npe-400"): + Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c7200") # Set default values for this platform self._ram = 512 diff --git a/gns3server/modules/dynamips/nodes/router.py b/gns3server/modules/dynamips/nodes/router.py index b3324185..a2ca1f4b 100644 --- a/gns3server/modules/dynamips/nodes/router.py +++ b/gns3server/modules/dynamips/nodes/router.py @@ -42,20 +42,22 @@ class Router(BaseVM): :param vm_id: Router instance identifier :param project: Project instance :param manager: Parent VM Manager + :param dynamips_id: ID to use with Dynamips :param platform: Platform of this router """ - _instances = [] + _dynamips_ids = {} _status = {0: "inactive", 1: "shutting down", 2: "running", 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) self._hypervisor = None + self._dynamips_id = dynamips_id self._closed = False self._name = name self._platform = platform @@ -81,12 +83,26 @@ class Router(BaseVM): self._confreg = "0x2102" self._console = None self._aux = None - self._mac_addr = None + self._mac_addr = "" self._system_id = "FTX0945W0MY" # processor board ID in IOS self._slots = [] self._ghost_flag = 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: 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) else: 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): router_info = {"name": self.name, "vm_id": self.id, "project_id": self.project.id, + "dynamips_id": self._dynamips_id, "platform": self._platform, "image": self._image, "startup_config": self._startup_config, @@ -138,14 +159,21 @@ class Router(BaseVM): return router_info + @classmethod + def reset(cls): + """ + Resets the instance count and the allocated instances list. + """ + + cls._dynamips_ids.clear() + @asyncio.coroutine def create(self): 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, - id=1, #FIXME: instance ID! + id=self._dynamips_id, platform=self._platform)) if not self._ghost_flag: @@ -270,6 +298,9 @@ class Router(BaseVM): self._manager.port_manager.release_console_port(self._aux) 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 @asyncio.coroutine diff --git a/gns3server/schemas/dynamips.py b/gns3server/schemas/dynamips.py index a707d0cc..d9fe845d 100644 --- a/gns3server/schemas/dynamips.py +++ b/gns3server/schemas/dynamips.py @@ -16,41 +16,102 @@ # along with this program. If not, see . -ROUTER_CREATE_SCHEMA = { +VM_CREATE_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", "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": { - "description": "Router name", + "description": "Dynamips VM instance name", "type": "string", "minLength": 1, }, - "router_id": { - "description": "VM/router instance ID", - "type": "integer" - }, "platform": { - "description": "router platform", + "description": "platform", "type": "string", "minLength": 1, "pattern": "^c[0-9]{4}$" }, - "chassis": { - "description": "router chassis model", + "image": { + "description": "path to the IOS image", "type": "string", "minLength": 1, - "pattern": "^[0-9]{4}(XM)?$" }, - "image": { - "description": "path to the IOS image file", + "startup_config": { + "description": "path to the IOS startup configuration file", "type": "string", - "minLength": 1 + "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", @@ -69,25 +130,352 @@ ROUTER_CREATE_SCHEMA = { "minLength": 1, "pattern": "^([0-9a-fA-F]{4}\\.){2}[0-9a-fA-F]{4}$" }, - "cloud_path": { - "description": "Path to the image in the cloud object store", + "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, "required": ["name", "platform", "image", "ram"] } -ROUTER_OBJECT_SCHEMA = { +VM_UPDATE_SCHEMA = { "$schema": "http://json-schema.org/draft-04/schema#", - "description": "Dynamips router instance", + "description": "Request validation to update a Dynamips VM instance", "type": "object", "properties": { "name": { - "description": "Dynamips router instance 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", + "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": { "description": "Dynamips router instance UUID", "type": "string", @@ -102,7 +490,214 @@ ROUTER_OBJECT_SCHEMA = { "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}$" }, + "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, - "required": ["name", "vm_id", "project_id"] + "required": ["name", "vm_id", "project_id", "dynamips_id"] } diff --git a/gns3server/utils/interfaces.py b/gns3server/utils/interfaces.py index 701bce48..27774eb3 100644 --- a/gns3server/utils/interfaces.py +++ b/gns3server/utils/interfaces.py @@ -49,7 +49,7 @@ def _get_windows_interfaces_from_registry(): return interfaces -def _get_windows_interfaces(): +def get_windows_interfaces(): """ Get Windows interfaces. @@ -94,7 +94,7 @@ def interfaces(): return else: try: - results = _get_windows_interfaces() + results = get_windows_interfaces() except ImportError: message = "pywin32 module is not installed, please install it on the server to get the available interface names" raise aiohttp.web.HTTPInternalServerError(text=message) diff --git a/old_tests/dynamips/.gitignore b/old_tests/dynamips/.gitignore deleted file mode 100644 index 39ffa4b5..00000000 --- a/old_tests/dynamips/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/c3725.image diff --git a/old_tests/dynamips/conftest.py b/old_tests/dynamips/conftest.py deleted file mode 100644 index ff70cd58..00000000 --- a/old_tests/dynamips/conftest.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/dynamips.stable b/old_tests/dynamips/dynamips.stable deleted file mode 100755 index 0af011ac..00000000 Binary files a/old_tests/dynamips/dynamips.stable and /dev/null differ diff --git a/old_tests/dynamips/test_atm_bridge.py b/old_tests/dynamips/test_atm_bridge.py deleted file mode 100644 index aed46f70..00000000 --- a/old_tests/dynamips/test_atm_bridge.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_atm_switch.py b/old_tests/dynamips/test_atm_switch.py deleted file mode 100644 index 6617b199..00000000 --- a/old_tests/dynamips/test_atm_switch.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_bridge.py b/old_tests/dynamips/test_bridge.py deleted file mode 100644 index ec415dbf..00000000 --- a/old_tests/dynamips/test_bridge.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_c1700.py b/old_tests/dynamips/test_c1700.py deleted file mode 100644 index 222d5a8f..00000000 --- a/old_tests/dynamips/test_c1700.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_c2600.py b/old_tests/dynamips/test_c2600.py deleted file mode 100644 index 53bfb0db..00000000 --- a/old_tests/dynamips/test_c2600.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/test_c2691.py b/old_tests/dynamips/test_c2691.py deleted file mode 100644 index 282b183b..00000000 --- a/old_tests/dynamips/test_c2691.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/test_c3600.py b/old_tests/dynamips/test_c3600.py deleted file mode 100644 index cd05add3..00000000 --- a/old_tests/dynamips/test_c3600.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/test_c3725.py b/old_tests/dynamips/test_c3725.py deleted file mode 100644 index bc3ffcbf..00000000 --- a/old_tests/dynamips/test_c3725.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/test_c3745.py b/old_tests/dynamips/test_c3745.py deleted file mode 100644 index 13d88583..00000000 --- a/old_tests/dynamips/test_c3745.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/test_c7200.py b/old_tests/dynamips/test_c7200.py deleted file mode 100644 index 48f1eb00..00000000 --- a/old_tests/dynamips/test_c7200.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_ethernet_switch.py b/old_tests/dynamips/test_ethernet_switch.py deleted file mode 100644 index 0f435f38..00000000 --- a/old_tests/dynamips/test_ethernet_switch.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_frame_relay_switch.py b/old_tests/dynamips/test_frame_relay_switch.py deleted file mode 100644 index b6dde5eb..00000000 --- a/old_tests/dynamips/test_frame_relay_switch.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_hub.py b/old_tests/dynamips/test_hub.py deleted file mode 100644 index d490cb11..00000000 --- a/old_tests/dynamips/test_hub.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_hypervisor.py b/old_tests/dynamips/test_hypervisor.py deleted file mode 100644 index 81a8176e..00000000 --- a/old_tests/dynamips/test_hypervisor.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/test_hypervisor_manager.py b/old_tests/dynamips/test_hypervisor_manager.py deleted file mode 100644 index c7e42734..00000000 --- a/old_tests/dynamips/test_hypervisor_manager.py +++ /dev/null @@ -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 diff --git a/old_tests/dynamips/test_nios.py b/old_tests/dynamips/test_nios.py deleted file mode 100644 index 691dac49..00000000 --- a/old_tests/dynamips/test_nios.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_router.py b/old_tests/dynamips/test_router.py deleted file mode 100644 index 4b0fd3db..00000000 --- a/old_tests/dynamips/test_router.py +++ /dev/null @@ -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() diff --git a/old_tests/dynamips/test_vmhandler.py b/old_tests/dynamips/test_vmhandler.py deleted file mode 100644 index e639d59f..00000000 --- a/old_tests/dynamips/test_vmhandler.py +++ /dev/null @@ -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) diff --git a/old_tests/test_jsonrpc.py b/old_tests/test_jsonrpc.py deleted file mode 100644 index eb6920a6..00000000 --- a/old_tests/test_jsonrpc.py +++ /dev/null @@ -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) diff --git a/tests/api/test_dynamips.py b/tests/api/test_dynamips.py new file mode 100644 index 00000000..3f18c6ad --- /dev/null +++ b/tests/api/test_dynamips.py @@ -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 . + +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 diff --git a/tests/modules/dynamips/test_dynamips_manager.py b/tests/modules/dynamips/test_dynamips_manager.py new file mode 100644 index 00000000..e0ddf9e1 --- /dev/null +++ b/tests/modules/dynamips/test_dynamips_manager.py @@ -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 . + + +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() diff --git a/tests/modules/dynamips/test_dynamips_router.py b/tests/modules/dynamips/test_dynamips_router.py new file mode 100644 index 00000000..c7fbb236 --- /dev/null +++ b/tests/modules/dynamips/test_dynamips_router.py @@ -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 . + +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" diff --git a/tests/modules/virtualbox/test_virtualbox_manager.py b/tests/modules/virtualbox/test_virtualbox_manager.py index fde3ca5b..1dc647d6 100644 --- a/tests/modules/virtualbox/test_virtualbox_manager.py +++ b/tests/modules/virtualbox/test_virtualbox_manager.py @@ -31,13 +31,13 @@ def manager(port_manager): return m -@patch("gns3server.config.Config.get_section_config", return_value={"vboxmanage_path": "/bin/test_fake"}) -def test_vm_invalid_vboxmanage_path(project, manager): - with pytest.raises(VirtualBoxError): - manager.find_vboxmanage() +def test_vm_invalid_vboxmanage_path(manager): + with patch("gns3server.config.Config.get_section_config", return_value={"vboxmanage_path": "/bin/test_fake"}): + with pytest.raises(VirtualBoxError): + manager.find_vboxmanage() -def test_vm_non_executable_vboxmanage_path(project, manager): +def test_vm_non_executable_vboxmanage_path(manager): tmpfile = tempfile.NamedTemporaryFile() with patch("gns3server.config.Config.get_section_config", return_value={"vboxmanage_path": tmpfile.name}): with pytest.raises(VirtualBoxError):