# son-emu
This is the repository of [SONATA's](http://sonata-nfv.eu) emulation platform.
-This emulation platform was created to support network service developers to locally prototype and test complete network service chains in realistic end-to-end multi-PoP scenarios. It allows the direct execution of real network functions, packaged as Docker containers, in emulated network topologies running locally on the network service developer's machine.
+This emulation platform was created to support network service developers to locally prototype and test complete network service chains in realistic end-to-end multi-PoP scenarios. It allows the execution of real network functions, packaged as Docker containers, in emulated network topologies running locally on the network service developer's machine.
### Cite this work
If you use son-emu for your research and/or other publications, please cite the following paper to reference our work:
-* Manuel Peuster, Holger Karl, and Steven van Rossem. "**MeDICINE: Rapid Prototyping of Production-Ready Network Services in Multi-PoP Environments.**" to appear in IEEE Conference on Network Function Virtualization and Software Defined Network (NFV-SDN), 2016.
- * Pre-print online: http://arxiv.org/abs/1606.05995
+* M. Peuster, H. Karl and S. van Rossem, **"MeDICINE: Rapid prototyping of production-ready network services in multi-PoP environments,"** 2016 IEEE Conference on Network Function Virtualization and Software Defined Networks (NFV-SDN), Palo Alto, CA, USA, 2016, pp. 148-153.
+doi: 10.1109/NFV-SDN.2016.7919490
+ * Link: http://ieeexplore.ieee.org/document/7919490/
+ * Pre-print: http://arxiv.org/abs/1606.05995
A short demo that showcases son-emu together with its dummy gatekeeper is available [here](https://www.youtube.com/watch?v=ZANz97pV9ao).
* `ansible` Install scripts
* `misc` Example packages and VNFs
* `src`
- * `emuvim` Emulator components
- * `api` API endpoint implementations
- * `rest` REST API for son-emu-cli
- * `sonata` Dummy gatekeeper API
- * `cli` Command line client to control the emulator
- * `dcemulator` Emulator core
- * `resourcemodel` Resource limitation models
- * `examples` Example topology scripts
- * `test` Test scripts
+ * `emuvim` Emulator components
+ * `api` API endpoint implementations
+ * `rest` REST API for son-emu-cli
+ * `sonata` Dummy gatekeeper API
+ * `openstack` OpenStack-like APIs for MANO integration
+ * `cli` Command line client to control the emulator
+ * `dashboard` A web-based dashboard to display the emulator's state
+ * `dcemulator` Emulator core
+ * `resourcemodel` Resource limitation models
+ * `examples` Example topology scripts
+ * `test` Test scripts
* `utils` Helper scripts for SONATA's CI/CD setup
#### Run Unit Tests
* `cd ~/son-emu`
* `sudo py.test -v src/emuvim/test/unittests`
+(To force using Python2: `python2 -m pytest -v src/emuvim/test/unittests`)
### Building
4. Follow/answer related [issues](https://github.com/sonata-nfv/son-emu/issues) (see Feedback-Chanel, below).
## Installation
-There are two ways to install and use son-emu. The simple one is to use Vagrant to create a VirtualBox-based VM on you machine that contains the pre-installed and configured emulator. The more complicated installation requires a freshly installed Ubuntu 14.04 LTS and is done by a ansible playbook.
+There are two ways to install and use son-emu. The simple one is to use Vagrant to create a VirtualBox-based VM on your machine that contains the pre-installed and configured emulator. The more complicated installation requires a freshly installed Ubuntu 16.04 LTS and is done by a ansible playbook.
### Vagrant Installation
### Ansible Installation
-* Requires: Ubuntu 14.04 LTS
+* Requires: Ubuntu 16.04 LTS
* `sudo apt-get install ansible git aptitude`
* `sudo vim /etc/ansible/hosts`
* Add: `localhost ansible_connection=local`
## Usage
### Examples
-#### Manual Usage Example:
This simple example shows how to start the emulator with a simple topology (terminal 1) and how to start (terminal 2) some empty VNF containers in the emulated datacenters (PoPs) by using the son-emu-cli.
* `containernet> vnf1 ifconfig`
* `containernet> vnf1 ping -c 2 vnf2`
-#### Dummy Gatekeeper Example:
-
-This example shows how to deploy a SONATA example package in the emulator using the dummy gatekeeper.
-
-* First terminal (start the emulation platform):
- * `sudo python src/emuvim/examples/sonata_y1_demo_topology_1.py`
-* Second terminal (deploy the example package):
- * Upload: `curl -i -X POST -F package=@sonata-demo-docker.son http://127.0.0.1:5000/packages`
- * Instantiate: `curl -X POST http://127.0.0.1:5000/instantiations -d "{}"`
- * Verify that service runs: `son-emu-cli compute list`
-
-Note: The [son-push](https://github.com/mpeuster/son-cli) tool can be used instead of CURL.
-
### Further Documentation
* [Full CLI command documentation](https://github.com/sonata-nfv/son-emu/wiki/CLI-Command-Overview)
* [Requirements for Docker containers executed by the emulator](https://github.com/sonata-nfv/son-emu/wiki/Container-Requirements)
+* [REST API](https://github.com/sonata-nfv/son-emu/wiki/REST-API-command-overview)
## License
* Hadi Razzaghi Kouchaksaraei (https://github.com/hadik3r)
* Wouter Tavernier (https://github.com/wtaverni)
* Geoffroy Chollon (https://github.com/cgeoffroy)
+* Eduard Maas (https://github.com/edmaas)
#### Feedback-Chanel
# no check if vnfs are really connected to this datacenter...
try:
- # get URL parameters
- data = request.args
- #then no data
+ # check json payload
+ logging.debug("json: {}".format(request.json))
+ logging.debug("args: {}".format(request.args))
+
+ data = request.json
+ if data is None:
+ data = request.args
if data is None:
data = {}
-
vnf_src_name = data.get("vnf_src_name")
vnf_dst_name = data.get("vnf_dst_name")
vnf_src_interface = data.get("vnf_src_interface")
import json
import networkx
-logging.basicConfig(level=logging.INFO)
+logging.basicConfig(level=logging.DEBUG)
CORS_HEADER = {'Access-Control-Allow-Origin': '*'}
# call DCNetwork method, not really datacenter specific API for now...
# no check if vnfs are really connected to this datacenter...
try:
- # check if json data is a dict
- data = request.args
- # try json payload
+ # check json payload
+ logging.debug("json: {}".format(request.json))
+ logging.debug("args: {}".format(request.args))
+
+ data = request.json
if data is None:
- data = request.json
- # then no data
+ data = request.args
if data is None:
data = {}
- elif type(data) is not dict:
- data = json.loads(request.json)
vnf_src_name = data.get("vnf_src_name")
vnf_dst_name = data.get("vnf_dst_name")
default command line client.
"""
- def __init__(self, listenip, port):
+ def __init__(self, listenip, port, DCnetwork=None):
self.ip = listenip
self.port = port
+ # connect this DC network to the rest api endpoint (needed for the networking and monitoring api)
+ self.connectDCNetwork(DCnetwork)
+
# setup Flask
# find directory of dashboard files
dashboard_file = pkg_resources.resource_filename('emuvim.dashboard', "index.html")
from random import randint
import ipaddress
import copy
+import time
logging.basicConfig()
LOG = logging.getLogger("sonata-dummy-gatekeeper")
# path to the VNFD for the SAP VNF that is deployed as internal SAP point
SAP_VNFD=None
+# Time in seconds to wait for vnf stop scripts to execute fully
+VNF_STOP_WAIT_TIME = 5
+
class Gatekeeper(object):
def __init__(self):
# instance_uuid = str(self.uuid.uuid4())
vnf_instances = self.instances[instance_uuid]["vnf_instances"]
+ # trigger stop skripts in vnf instances and wait a few seconds for completion
+ self._trigger_emulator_stop_scripts_in_vnfis(vnf_instances)
+ time.sleep(VNF_STOP_WAIT_TIME)
+
for v in vnf_instances:
self._stop_vnfi(v)
t.daemon = True
t.start()
+ def _trigger_emulator_stop_scripts_in_vnfis(self, vnfi_list):
+ for vnfi in vnfi_list:
+ config = vnfi.dcinfo.get("Config", dict())
+ env = config.get("Env", list())
+ for env_var in env:
+ var, cmd = map(str.strip, map(str, env_var.split('=', 1)))
+ if var=="SON_EMU_CMD_STOP":
+ LOG.info("Executing stop script in %r: %r" % (vnfi.name, cmd))
+ # execute command in new thread to ensure that GK is not blocked by VNF
+ t = threading.Thread(target=vnfi.cmdPrint, args=(cmd,))
+ t.daemon = True
+ t.start()
+
+
+
def _unpack_service_package(self):
"""
unzip *.son file and store contents in CATALOG_FOLDER/services/<service_uuid>/
Popen(['xterm', '-xrm', 'XTerm.vt100.allowTitleOps: false', '-T', vnf_name,
'-e', "docker exec -it mn.{0} /bin/bash".format(vnf_name)])
-parser = argparse.ArgumentParser(description="""son-emu compute
+parser = argparse.ArgumentParser(description="""son-emu-cli compute
Examples:
- son-emu-cli compute start -d dc2 -n client -i sonatanfv/sonata-iperf3-vnf
parser.add_argument(
"--endpoint", "-e", dest="endpoint",
default="http://127.0.0.1:5001",
- help="UUID of the plugin to be manipulated.")
+ help="REST API endpoint of son-emu (default:http://127.0.0.1:5001)")
def main(argv):
print (tabulate(table, headers=headers, tablefmt="grid"))
-parser = argparse.ArgumentParser(description='son-emu datacenter')
+parser = argparse.ArgumentParser(description='son-emu-cli datacenter')
parser.add_argument(
"command",
choices=['list', 'status'],
parser.add_argument(
"--endpoint", "-e", dest="endpoint",
default="http://127.0.0.1:5001",
- help="UUID of the plugin to be manipulated.")
+ help="REST API endpoint of son-emu (default:http://127.0.0.1:5001)")
def main(argv):
print("Command not implemented.")
def setup_metric(self, args):
- vnf_name = self._parse_vnf_name(args.get("vnf_name"))
- vnf_interface = self._parse_vnf_interface(args.get("vnf_name"))
- response = put("%s/restapi/monitor/interface/%s/%s/%s" %
- (args.get("endpoint"),
- vnf_name,
- vnf_interface,
- args.get("metric")))
- pp.pprint(response.json())
+ params = self._create_dict(
+ vnf_name=self._parse_vnf_name(args.get("vnf_name")),
+ vnf_interface = self._parse_vnf_interface(args.get("vnf_name")),
+ metric = args.get("metric"))
+
+ url = "{0}/restapi/monitor/interface".format(args.get("endpoint"))
+ response = put(url, params=params)
+ pp.pprint(response.text)
def stop_metric(self, args):
- vnf_name = self._parse_vnf_name(args.get("vnf_name"))
- vnf_interface = self._parse_vnf_interface(args.get("vnf_name"))
+ params = self._create_dict(
+ vnf_name=self._parse_vnf_name(args.get("vnf_name")),
+ vnf_interface=self._parse_vnf_interface(args.get("vnf_name")),
+ metric=args.get("metric"))
- response = delete("%s/restapi/monitor/interface/%s/%s/%s" %
- (args.get("endpoint"),
- vnf_name,
- vnf_interface,
- args.get("metric")))
- pp.pprint(response.json())
+ url = "{0}/restapi/monitor/interface".format(args.get("endpoint"))
+ response = put(url, params=params)
+ pp.pprint(response.text)
def setup_flow(self, args):
- vnf_name = self._parse_vnf_name(args.get("vnf_name"))
- vnf_interface = self._parse_vnf_interface(args.get("vnf_name"))
+ params = self._create_dict(
+ vnf_name=self._parse_vnf_name(args.get("vnf_name")),
+ vnf_interface=self._parse_vnf_interface(args.get("vnf_name")),
+ metric=args.get("metric"),
+ cookie=args.get("cookie"))
- response = put("%s/restapi/monitor/flow/%s/%s/%s/%s" %
- (args.get("endpoint"),
- vnf_name,
- vnf_interface,
- args.get("metric"),
- args.get("cookie")))
-
- pp.pprint(response.json())
+ url = "{0}/restapi/monitor/flow".format(args.get("endpoint"))
+ response = put(url, params=params)
+ pp.pprint(response.text)
def stop_flow(self, args):
- vnf_name = self._parse_vnf_name(args.get("vnf_name"))
- vnf_interface = self._parse_vnf_interface(args.get("vnf_name"))
+ params = self._create_dict(
+ vnf_name=self._parse_vnf_name(args.get("vnf_name")),
+ vnf_interface=self._parse_vnf_interface(args.get("vnf_name")),
+ metric=args.get("metric"),
+ cookie=args.get("cookie"))
- response = delete("%s/restapi/monitor/flow/%s/%s/%s/%s" %
- (args.get("endpoint"),
- vnf_name,
- vnf_interface,
- args.get("metric"),
- args.get("cookie")))
-
- pp.pprint(response.json())
+ url = "{0}/restapi/monitor/flow".format(args.get("endpoint"))
+ response = put(url, params=params)
+ pp.pprint(response.text)
def prometheus(self, args):
# This functions makes it more user-friendly to create the correct prometheus query
vnf_interface = self._parse_vnf_interface(args.get("vnf_name"))
dc_label = args.get("datacenter")
query = args.get("query")
+
vnf_status = get("%s/restapi/compute/%s/%s" %
(args.get("endpoint"),
args.get("datacenter"),
return vnf_interface
-parser = argparse.ArgumentParser(description='son-emu monitor')
+ def _create_dict(self, **kwargs):
+ return kwargs
+
+parser = argparse.ArgumentParser(description='son-emu-cli monitor')
parser.add_argument(
"command",
choices=['setup_metric', 'stop_metric', 'setup_flow', 'stop_flow','prometheus'],
parser.add_argument(
"--endpoint", "-e", dest="endpoint",
default="http://127.0.0.1:5001",
- help="UUID of the plugin to be manipulated.")
+ help="REST API endpoint of son-emu (default:http://127.0.0.1:5001)")
def main(argv):
args = vars(parser.parse_args(argv))
partner consortium (www.sonata-nfv.eu).
"""
from requests import get,put, delete
-import pprint
import argparse
-pp = pprint.PrettyPrinter(indent=4)
class RestApiClient():
print("Command not implemented.")
def add(self, args):
- vnf_src_name = self._parse_vnf_name(args.get("source"))
- vnf_dst_name = self._parse_vnf_name(args.get("destination"))
-
params = self._create_dict(
+ vnf_src_name=self._parse_vnf_name(args.get("source")),
+ vnf_dst_name = self._parse_vnf_name(args.get("destination")),
vnf_src_interface=self._parse_vnf_interface(args.get("source")),
vnf_dst_interface=self._parse_vnf_interface(args.get("destination")),
weight=args.get("weight"),
cookie=args.get("cookie"),
priority=args.get("priority"))
- response = put("%s/restapi/network/%s/%s" %
- (args.get("endpoint"),
- vnf_src_name,
- vnf_dst_name),
- json=params)
- pp.pprint(response.json())
+ response = put("{0}/restapi/network".format(args.get("endpoint")),
+ params=params)
+ print(self._nice_print(response.text))
def remove(self, args):
- vnf_src_name = self._parse_vnf_name(args.get("source"))
- vnf_dst_name = self._parse_vnf_name(args.get("destination"))
-
params = self._create_dict(
+ vnf_src_name = self._parse_vnf_name(args.get("source")),
+ vnf_dst_name = self._parse_vnf_name(args.get("destination")),
vnf_src_interface=self._parse_vnf_interface(args.get("source")),
vnf_dst_interface=self._parse_vnf_interface(args.get("destination")),
weight=args.get("weight"),
cookie=args.get("cookie"),
priority=args.get("priority"))
- response = delete("%s/restapi/network/%s/%s" %
- (args.get("endpoint"),
- vnf_src_name,
- vnf_dst_name),
- json=params)
- pp.pprint(response.json())
+ response = delete("{0}/restapi/network".format(args.get("endpoint")),
+ params=params)
+ print(self._nice_print(response.text))
def _parse_vnf_name(self, vnf_name_str):
vnf_name = vnf_name_str.split(':')[0]
def _create_dict(self, **kwargs):
return kwargs
-parser = argparse.ArgumentParser(description='son-emu network')
+ def _nice_print(self, text):
+ # some modules seem to return unicode strings where newlines, other special characters are escaped
+ text = str(text).replace('\\n', '\n')
+ text = str(text).replace('\\"', '"')
+ return text
+
+parser = argparse.ArgumentParser(description='son-emu-cli network')
parser.add_argument(
"command",
choices=['add', 'remove'],
"--weight", "-w", dest="weight",
help="weight edge attribute to calculate the path")
parser.add_argument(
- "--priority", "-p", dest="priority", default="0",
+ "--priority", "-p", dest="priority", default="1000",
help="priority of flow rule")
parser.add_argument(
"--match", "-m", dest="match",
"--bidirectional", "-b", dest="bidirectional", action='store_true',
help="add/remove the flow entries from src to dst and back")
parser.add_argument(
- "--cookie", "-c", dest="cookie",
+ "--cookie", "-c", dest="cookie", default="10",
help="cookie for this flow, as easy to use identifier (eg. per tenant/service)")
parser.add_argument(
"--endpoint", "-e", dest="endpoint",
default="http://127.0.0.1:5001",
- help="UUID of the plugin to be manipulated.")
+ help="REST API endpoint of son-emu (default:http://127.0.0.1:5001)")
def main(argv):
args = vars(parser.parse_args(argv))
import re
import requests
import os
+import json
from mininet.net import Containernet
from mininet.node import Controller, DefaultController, OVSSwitch, OVSKernelSwitch, Docker, RemoteController
# default CPU period used for cpu percentage-based cfs values (microseconds)
CPU_PERIOD = 1000000
+# default priority setting for added flow-rules
+DEFAULT_PRIORITY = 1000
+# default cookie number for new flow-rules
+DEFAULT_COOKIE = 10
+
class DCNetwork(Containernet):
"""
Wraps the original Mininet/Containernet class and provides
switch_inport_nr = self.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
current_hop = next_hop
- return "path {2} between {0} and {1}".format(vnf_src_name, vnf_dst_name, cmd)
+ flow_options = {
+ 'priority':kwargs.get('priority', DEFAULT_PRIORITY),
+ 'cookie':kwargs.get('cookie', DEFAULT_COOKIE),
+ 'vlan':kwargs['vlan'],
+ 'path':kwargs['path'],
+ 'match_input':kwargs.get('match')
+ }
+ flow_options_str = json.dumps(flow_options, indent=1)
+ return "success: {2} between {0} and {1} with options: {3}".format(vnf_src_name, vnf_dst_name, cmd, flow_options_str)
def _set_flow_entry_ryu_rest(self, node, switch_inport_nr, switch_outport_nr, **kwargs):
match = 'in_port=%s' % switch_inport_nr
index = kwargs.get('pathindex')
vlan = kwargs.get('vlan')
- priority = kwargs.get('priority')
+ priority = kwargs.get('priority', DEFAULT_PRIORITY)
# flag to not set the ovs port vlan tag
skip_vlan_tag = kwargs.get('skip_vlan_tag')
# table id to put this flowentry
def create_topology1():
# create topology
- net = DCNetwork(controller=RemoteController, monitor=False, enable_learning=True)
+ net = DCNetwork(controller=RemoteController, monitor=True, enable_learning=True)
dc1 = net.addDatacenter("dc1")
dc2 = net.addDatacenter("dc2")
dc3 = net.addDatacenter("dc3")
this API, e.g., start/stop/list compute instances.
"""
# create a new instance of a endpoint implementation
- rapi1 = RestApiEndpoint("127.0.0.1", 5001)
+ rapi1 = RestApiEndpoint("127.0.0.1", 5001, net)
# connect data centers to this endpoint
rapi1.connectDatacenter(dc1)
rapi1.connectDatacenter(dc2)
specific controller functionality.
"""
self.net = DCNetwork(controller=controller, **kwargs)
- self.api = RestApiEndpoint("127.0.0.1", 5001)
+ self.api = RestApiEndpoint("127.0.0.1", 5001, self.net)
# add some switches
# start from s1 because ovs does not like to have dpid = 0
# and switch name-number is being used by mininet to set the dpid
class testEmulatorNetworking( SimpleTestTopology ):
+ def testSDNChainingSingleService_withLearning(self):
+ """
+ Create a two data centers and interconnect them with additional
+ switches between them.
+ Uses Ryu SDN controller.
+ Connect the Docker hosts to different datacenters and setup the links between.
+ """
+ # create network
+ self.createNet(
+ nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
+ autolinkswitches=True,
+ controller=RemoteController,
+ enable_learning=True)
+ # setup links
+ self.net.addLink(self.dc[0], self.s[0])
+ self.net.addLink(self.s[2], self.dc[1])
+ # start Mininet network
+ self.startNet()
+
+ # add compute resources
+ vnf1 = self.dc[0].startCompute("vnf1", network=[{'id':'intf1', 'ip':'10.0.10.1/24'}])
+ vnf2 = self.dc[1].startCompute("vnf2", network=[{'id':'intf2', 'ip':'10.0.10.2/24'}])
+ # check number of running nodes
+ self.assertTrue(len(self.getContainernetContainers()) == 2)
+ self.assertTrue(len(self.net.hosts) == 2)
+ self.assertTrue(len(self.net.switches) == 5)
+ # check status
+ # check get status
+ s1 = self.dc[0].containers.get("vnf1").getStatus()
+ print s1
+ self.assertTrue(s1["name"] == "vnf1")
+ self.assertTrue(s1["state"]["Running"])
+ self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
+ self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1/24')
+
+ s2 = self.dc[1].containers.get("vnf2").getStatus()
+ print s2
+ self.assertTrue(s2["name"] == "vnf2")
+ self.assertTrue(s2["state"]["Running"])
+ self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
+ self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2/24')
+
+ # should be connected because learning = True
+ self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
+ # setup links
+ self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='add-flow')
+ # should still be connected
+ self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
+ # stop Mininet network
+ self.stopNet()
+
def testSDNChainingSingleService(self):
"""
Create a two data centers and interconnect them with additional
print('network add vnf1 vnf2->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli network add -src vnf1 -dst vnf2 -b -c 10", shell=True)
+ output = subprocess.check_output("son-emu-cli network add -src vnf1 -dst vnf2 -b -c 10", shell=True)
+ self.assertTrue("add-flow" in output)
+ self.assertTrue("success" in output)
+
print('network remove vnf1 vnf2->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli network remove -src vnf1 -dst vnf2 -b", shell=True)
+ output = subprocess.check_output("son-emu-cli network remove -src vnf1 -dst vnf2 -b", shell=True)
+ self.assertTrue("del-flows" in output)
+ self.assertTrue("success" in output)
print('>>>>> checking --> son-emu-cli compute stop -d datacenter0 -n vnf2 ->>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli compute stop -d datacenter0 -n vnf2", shell=True)
+ output = subprocess.check_output("son-emu-cli compute stop -d datacenter0 -n vnf2", shell=True)
# check number of running nodes
self.assertTrue(len(self.getContainernetContainers()) == 2)
print('>>>>> checking --> son-emu-cli compute list ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli compute list", shell=True)
output = subprocess.check_output("son-emu-cli compute list", shell=True)
# check datacenter list result
print('>>>>> checking --> son-emu-cli compute status -d datacenter0 -n vnf1 ->>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli compute status -d datacenter0 -n vnf1", shell=True)
output = subprocess.check_output("son-emu-cli compute status -d datacenter0 -n vnf1", shell=True)
output = ast.literal_eval(output)
print('>>>>> checking --> son-emu-cli datacenter list ->>>>>>>>>>>>>>>>>>>>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli datacenter list", shell=True)
output = subprocess.check_output("son-emu-cli datacenter list", shell=True)
-
# check datacenter list result
-
self.assertTrue("datacenter0" in output)
print('->>>>> checking --> son-emu-cli datacenter status -d datacenter0 ->>>>>>>>')
print('->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
- subprocess.call("son-emu-cli datacenter status -d datacenter0", shell=True)
output = subprocess.check_output("son-emu-cli datacenter status -d datacenter0", shell=True)
-
# check datacenter status result
self.assertTrue("datacenter0" in output)